Sed 명령이 원치 않는 새 줄을 생성합니다.

Sed 명령이 원치 않는 새 줄을 생성합니다.

내 소스 파일에는 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를 사용합니다 .catmlr-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

관련 정보