내 소스 파일에는 6줄만 있지만 sed 명령을 사용하여 텍스트 한정자를 적용하면 각 입력 줄에 대해 2줄이 생성됩니다.
소스 파일:
September 2022||2022|||13564|7JM9LF |DANIEL, PAPERMAN
September 2022||2022|||48917|7CX04Q |BROWN, RADY
September 2022||2022|||177456|75YBGL |LAYYNE, MAXWELL
September 2022||2022|||5326|774YMX |BROWN, WHITE
사용된 명령:
sed 's/\([^|]*\)/\"&\"/g' ./src_mod.txt > tgt.txt
답변1
|
정의된 모든 필드 주위에 따옴표를 추가 하려고 하는 것 같습니다 . 추가 줄 바꿈을 얻는 이유는 Windows 스타일 줄 끝이 있기 때문일 가능성이 높습니다.
그냥 실행 dos2unix src_mod.txt
하거나 sed -i 's/\r//' src_mod.txt
.
원래 방법도 작동하지만 원하는 것을 얻을 수 있는 다른 방법은 다음과 같습니다.
$ sed -E 's/([^|]*)(\||$)/"\1"\2/g' file
"September 2022"|""|"2022"|""|""|"13564"|"7JM9LF "|"DANIEL, PAPERMAN"
"September 2022"|""|"2022"|""|""|"48917"|"7CX04Q "|"BROWN, RADY"
"September 2022"|""|"2022"|""|""|"177456"|"75YBGL "|"LAYYNE, MAXWELL"
"September 2022"|""|"2022"|""|""|"5326"|"774YMX "|"BROWN, WHITE"
또는 다음을 사용할 수 없는 경우 -E
:
sed 's/\([^|]*\)\(|\|$\)/"\1"\2/g' file
또는 펄:
$ perl -F'\|' -lane 'print join("|", map{ qq/"$_"/} @F)' file
"September 2022"|""|"2022"|""|""|"13564"|"7JM9LF "|"DANIEL, PAPERMAN"
"September 2022"|""|"2022"|""|""|"48917"|"7CX04Q "|"BROWN, RADY"
"September 2022"|""|"2022"|""|""|"177456"|"75YBGL "|"LAYYNE, MAXWELL"
"September 2022"|""|"2022"|""|""|"5326"|"774YMX "|"BROWN, WHITE"
또는 펄:
$ perl -F'\|' -lane 'print "\"",join("\"|\"", @F), "\""' file
"September 2022"|""|"2022"|""|""|"13564"|"7JM9LF "|"DANIEL, PAPERMAN"
"September 2022"|""|"2022"|""|""|"48917"|"7CX04Q "|"BROWN, RADY"
"September 2022"|""|"2022"|""|""|"177456"|"75YBGL "|"LAYYNE, MAXWELL"
"September 2022"|""|"2022"|""|""|"5326"|"774YMX "|"BROWN, WHITE"
답변2
문제는 입력 파일이 Unix 텍스트 파일이 아니라는 것일 수 있습니다. DOS 텍스트 파일일 수 있습니다.
CSV 인식 도구는 입력이 DOS 텍스트 파일임을 무시하므로 기본적으로 필드를 올바르게 참조할 수 있습니다.
다음은 csvformat
파이프로 구분된 모든 필드를 참조하는 데 사용됩니다. 이 연습의 입력은 DOS 텍스트 파일로 변환되었습니다.
$ csvformat -d '|' -D '|' -U1 file
"September 2022"|""|"2022"|""|""|"13564"|"7JM9LF "|"DANIEL, PAPERMAN"
"September 2022"|""|"2022"|""|""|"48917"|"7CX04Q "|"BROWN, RADY"
"September 2022"|""|"2022"|""|""|"177456"|"75YBGL "|"LAYYNE, MAXWELL"
"September 2022"|""|"2022"|""|""|"5326"|"774YMX "|"BROWN, WHITE"
csvformat
(부분csvkit) 기본적으로 실제로 인용해야 하는 필드만 인용됩니다. 왜냐하면 필드 구분 기호를 기본 쉼표로 변경하면 각 레코드의 마지막 필드를 인용해야 하기 때문입니다.
$ csvformat -d '|' file
September 2022,,2022,,,13564,7JM9LF ,"DANIEL, PAPERMAN"
September 2022,,2022,,,48917,7CX04Q ,"BROWN, RADY"
September 2022,,2022,,,177456,75YBGL ,"LAYYNE, MAXWELL"
September 2022,,2022,,,5326,774YMX ,"BROWN, WHITE"
밀러CSV를 지원하는 또 다른 도구는 다음과 같습니다.
$ mlr --csv --fs pipe -N --quote-all cat file
"September 2022"|""|"2022"|""|""|"13564"|"7JM9LF "|"DANIEL, PAPERMAN"
"September 2022"|""|"2022"|""|""|"48917"|"7CX04Q "|"BROWN, RADY"
"September 2022"|""|"2022"|""|""|"177456"|"75YBGL "|"LAYYNE, MAXWELL"
"September 2022"|""|"2022"|""|""|"5326"|"774YMX "|"BROWN, WHITE"
또한 이 도구는 기본적으로 필요한 것만 인용하도록 설정되어 있습니다.
$ mlr --csv --ifs pipe -N cat file
September 2022,,2022,,,13564,7JM9LF ,"DANIEL, PAPERMAN"
September 2022,,2022,,,48917,7CX04Q ,"BROWN, RADY"
September 2022,,2022,,,177456,75YBGL ,"LAYYNE, MAXWELL"
September 2022,,2022,,,5326,774YMX ,"BROWN, WHITE"
clean-whitespace
필드에서 측면 공백을 제거하거나 입력에 실제로 제목이 있는 경우 명령에 not를 사용합니다 .cat
mlr
-N
답변3
sed
이렇게 하지 않으면 사용자가 지시하지 않는 한 개행 문자가 추가되지 않습니다.
여기서 입력 파일에는 MS-DOS CRLF 줄 끝이 있을 가능성이 높으므로 Unix 관점에서(줄은 LF로 구분됨) 줄이 CR 문자로 끝나는 것처럼 나타나므로 출력에서 다음으로 끝나는 줄이 표시됩니다 |"CR"
. 스크린샷을 찍은 응용 프로그램이 CR을 줄 구분 기호로 렌더링하는 이유도 있습니다.
여기서는 이러한 파일을 Unix 형식으로 변환하려고 합니다. dos2unix
이 작업을 수행하는 도구이지만 없는 경우 perl
두 가지를 모두 사용하여 후행 CR 문자를 제거하고 각 필드 주위에 따옴표를 추가할 수 있습니다.
perl -lpe 's/\r$//; $_ = join "|", map qq("$_"), split /\|/, $_, -1' <src_mod.txt >tgt.txt
빈 줄은 빈 필드를 포함하는 것이 아니라 0 필드 목록으로 처리됩니다.
삭제할 수도 있습니다모두줄 끝 문자뿐만 아니라 CR 문자 tr
를 다음으로 바꾸세요 sed
.
<src_mod.txt tr -d '\r' | sed 's/[^|]*/"&"/g' >tgt.txt
"
대체 시 이스케이프가 없어야 하며, 일치하는 전체 텍스트가 호출되므로 캡처링 그룹을 사용할 필요가 없습니다 ( 캡처 \(...\)
링 그룹 일치를 호출하는 데 사용하는 것).&
\1