![문자열에서 \n을 제거하는 방법](https://linux55.com/image/15038/%EB%AC%B8%EC%9E%90%EC%97%B4%EC%97%90%EC%84%9C%20%5Cn%EC%9D%84%20%EC%A0%9C%EA%B1%B0%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
문자열의 23열에 \n이 있는 탭으로 구분된 텍스트 파일이 있는데 이로 인해 다음 줄로 넘어갑니다.
공백이 활성화된 vi에서 텍스트 파일을 열면 DESCR2 필드의 값에 문자열을 분리하는 빈 줄이 있는 것을 볼 수 있습니다.
문자열은 탭으로 구분된 문자 내에 포함되어 있으며 \n을 제거하고 1 필드에 있는 동안 문자열을 ABC 123에 연결하려고 합니다.
나는 이것을 시도했지만 tr -d '\n' < file.txt
모든 행을 1 행으로 바꿉니다. 이 열에서\n\n을 제거하고 싶습니다.
나도 시도해 보았지만 sed 's/\n\n//' file.txt
효과가 없었습니다. vi에서\n\n을 검색하고 바꿀 수 있지만 sed를 사용하면 동일한 결과를 얻을 수 없습니다.
예:
\t"ABC\n
\n
123"\t
원하는 출력:
\t"ABC 123"\t
답변1
탭 문자를 필드 구분 기호로 사용하는 올바른 형식의 CSV 파일이 있는 것 같습니다. 표시된 예의 경우처럼 올바르게 인용되는 한 필드에 줄 바꿈을 포함할 수 있습니다. 모든 CSV 파서는 데이터를 읽는 데 아무런 문제가 없습니다.
이러한 개행 문자를 제거하려면 다음과 같은 CSV 파서를 사용할 수 있습니다.csvkit
.
다음과 같은 샘플 파일을 사용하여 작업하겠습니다.
$ cat -t file.csv
col1^Icol2^Icol3
col1^I"ABC
123"^Icol3
col1^Icol2^Icol3
각각은 ^I
탭 문자입니다. 두 번째 줄의 두 번째 필드에는 두 개의 연속된 개행 문자가 포함되어 있으며, 이를 단일 공백 문자로 안전하게 대체하려고 합니다.
저는 CSV 데이터를 JSON 문서로 변환하는 csvjson
from 을 사용하고 있습니다. csvkit
이렇게 하면 데이터를 수정하는 데 사용하기가 약간 더 쉬워지며 jq
데이터를 다시 CSV 형식으로 변환하는 데에도 사용할 수 있습니다.
$ csvjson -t -H file.csv | jq -r '.[] | [ .[] | values |= gsub("\n\n";" ") ] | @csv'
"col1","col2","col3"
"col1","ABC 123","col3"
"col1","col2","col3"
여기에 사용된 명령은 csvjson
CSV 파일의 각 행을 JSON 개체로 변환합니다. 이 -t
옵션은 입력이 탭 문자를 구분 기호로 사용하고 -H
열 머리글이 없음을 도구에 알립니다.
JSON 개체를 배열에 넣고 읽어서 값을 추출합니다( 원본 CSV 파일에는 헤더가 없거나 질문에서 언급한 대로 적어도 없기 때문에 데이터는 , 등과 같은 키 jq
에 할당됩니다 ). 공백을 사용하여 간단한 교체를 적용합니다. 연속된 개행의 모든 쌍을 교체합니다.a
b
c
gsub()
gsub()
분명히 위에 사용된 정규식을 변경 \n+
하여 연속된 개행 문자를 단일 공백 문자로 바꿀 수 있습니다.
그런 다음 운영자는 @csv
CSV 출력 형식의 배열 형태로 데이터 세트를 받습니다.
csvformat
기본 필드 구분 기호를 쉼표에서 다시 탭으로 변경하려면 -T
(탭으로 구분된 출력의 경우) 및 (CSV 입력에 헤더 없음) 옵션을 사용하여 -H
결과를 파이프하십시오 .
$ csvjson -t -H file.csv | jq -r '.[] | [ .[] | values |= gsub("\n\n";" ") ] | @csv' | csvformat -T -H
col1 col2 col3
col1 ABC 123 col3
col1 col2 col3
csvformat
인용이 필요한 필드는 자동으로 인용됩니다.
이 csvformat
도구도 마찬가지입니다 csvkit
.
참고로 에서 만든 중간 JSON 문서는 csvjson
다음과 같습니다( 로 미화 jq
).
[
{
"a": "col1",
"b": "col2",
"c": "col3"
},
{
"a": "col1",
"b": "ABC\n\n123",
"c": "col3"
},
{
"a": "col1",
"b": "col2",
"c": "col3"
}
]
답변2
GoCSV가 이를 수행할 수 있습니다.
TSV를 CSV로 변환하고 줄 바꿈을 바꿉니다.
다음과 같은 TSV 파일로 시작하여 데이터를 시뮬레이션해 보겠습니다.
+--------+--------+--------+--------+--------+
| Col21 | Col22 | DESCR2 | Col24 | Col25 |
+--------+--------+--------+--------+--------+
| data21 | data22 | ABC | data24 | data25 |
| | | | | |
| | | 123 | | |
+--------+--------+--------+--------+--------+
첫 번째 단계는 TSV를 모든 GoCSV 명령에서 사용되는 형식인 CSV로 변환하는 것입니다. 또한 DESC2 값을 포함하는 새 열을 끝에 추가하고 줄 바꿈을 대체했습니다. -N~이다이름새 열-티SPRIG 입니다주형replace
필요한 함수를 사용하면 ( .DESCR2 | replace
"DESCR2 열을 대체 함수에 넣습니다"와 같이 읽습니다):
gocsv delim \
-i "\t" \
-o "," \
input.tsv |
gocsv add \
-n DESCR2_replaced \
-t '{{ .DESCR2 | replace "\n" " " }}' \
> replaced.csv
.csv 교체
+--------+--------+--------+--------+--------+-----------------+
| Col21 | Col22 | DESCR2 | Col24 | Col25 | DESCR2_replaced |
+--------+--------+--------+--------+--------+-----------------+
| data21 | data22 | ABC | data24 | data25 | ABC 123 |
| | | | | | |
| | | 123 | | | |
+--------+--------+--------+--------+--------+-----------------+
새 열로 교체하고 이전 열로 이름 바꾸기
_replaced 열의 데이터를 정규화한 후 "선택하다기존 DESCR2를 제거하고 새 DESCR2_replaced를 "선택"하여 교체합니다. 그런 다음이름을 바꿔라DESCR2_는 DESCR2로 다시 대체됩니다. 내 예에서는 열이 6개뿐이므로-씨 기둥색인은 23개 이상의 열 파일에 있는 색인과 다릅니다.
gocsv select \
-c 1-2,6,4-5 \
replaced.csv |
gocsv rename \
-c 3 \
-names DESCR2 \
> final.csv
최종.csv
+--------+--------+----------+--------+--------+
| Col21 | Col22 | DESCR2 | Col24 | Col25 |
+--------+--------+----------+--------+--------+
| data21 | data22 | ABC 123 | data24 | data25 |
+--------+--------+----------+--------+--------+
TSV로 다시 변환
gocsv delim \
-i "," \
-o "\t" \
final.csv \
> final.tsv
큰 파이프
gocsv delim \
-i "\t" \
-o "," \
input.tsv \
| gocsv add \
-n DESCR2_replaced \
-t '{{ .DESCR2 | replace "\n" " " }}' \
| gocsv select \
-c 1-2,6,4-5 \
| gocsv rename \
-c 3 \
-names DESCR2 \
| gocsv delim \
-i "," \
-o "\t" \
> final.tsv
답변3
다음을 사용해 보셨나요 sed ':a;N;$!ba;s/\\n\n/ /g' file.txt
?
내가 찾은이것답변에는 sed를 사용하여 개행 문자를 제거하고 \\n
추가 백슬래시를 추가하여 특수 문자를 이스케이프 처리하는 방법이 자세히 설명되어 있습니다.
답변4
간단한 sed 실행에는 패턴 공간에 언제든지 한 줄만 포함되므로 sed 구문이 작동하지 않습니다. (중복되지 않은 경우 유사한) 질문에는 sed를 사용하여 여러 줄 편집을 처리하는 방법을 설명하는 답변이 있습니다.여기. TLDR은 형편없고 구문이 고통스럽다는 것입니다.
마찬가지로 tr은 항상 하나의 행만 보기 때문에 실패합니다.
내 생각에는 여러 줄을 처리하는 가장 쉬운 방법은 Perl을 사용하는 것입니다.
perl -0777 -pe 's/\n\n/ /igs' file.txt
여기서 -0777은 Perl에게 전체 파일을 일치시키라고 지시하는 반면, -pe는 찾아서 바꾸기만 합니다.
이 버전은 인라인 편집을 위해 -i를 사용합니다.
perl -0777 -pe 's/\n\n/ /igs' -i file.txt
편집하다: 표시된 특수 문자로 바꾸려면 정규 표현식에서 해당 특수 문자를 올바르게 이스케이프 처리해야 할 수도 있습니다. \n