데이터 파일에서 특정 큰따옴표만 바꾸기

데이터 파일에서 특정 큰따옴표만 바꾸기

파이프를 열 구분 기호로 사용하고 큰따옴표를 텍스트 구분 기호로 사용하여 데이터베이스에서 플랫 파일로 데이터를 추출하고 있습니다.

데이터 파일은 다음과 같습니다.

"164829" | "collection 1" | "wood plank 2" x 4" long" | "23.5" 
"2017"|"S"|"221318"|"WE"|"20170118"|"Someones name"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536"|"00090"|"LOCAL00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|" "|" "|" "|" "|"005"|"00000000"|" "|" "|"1785"|"50228"|"R"|"2017"|"NMT CAUTION| 5" X 3" NAT ON BLK"|" "|" "|"USD"|"7444"|" "|"000"|"COIN"|"04"|35.00|"00"

두 번째 큰따옴표로 데이터(텍스트 구분 기호 제외)를 이스케이프할 수 있는 모든 경우를 찾을 수 있는 명령/스크립트는 무엇입니까?

최종 결과는 다음과 같아야 합니다.

"164829" | "collection 1" | "wood plank 2"" x 4"" long" | "23.5"
"2017"|"S"|"221318"|"WE"|"20170118"|"Someones name"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536"|"00090"|"LOCAL00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|" "|" "|" "|" "|"005"|"00000000"|" "|" "|"1785"|"50228"|"R"|"2017"|"NMT CAUTION| 5"" X 3"" NAT ON BLK"|" "|" "|"USD"|"7444"|" "|"000"|"COIN"|"04"|35.00|"00"

답변1

정규식만 사용하면 약간 까다롭지만 몇 단계만 거치면 완료할 수 있습니다. 여기에 내가 사용하는 Perl 스크립트가 있습니다(예측을 사용하기 때문에 sed를 사용할 수 없습니다).

perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;s/~~//g' inputfile.txt

( perl -pi -e입력 파일을 편집하려는 경우 사용)

스크립트는 다음 단계를 수행합니다.

  1. 외부 공백 텍스트를 무시하고 |"{...}"|(줄 시작) "{...}"| 또는 |"{...}"(줄 끝) 내의 모든 항목을 찾습니다. 외부 비트를 다음으로 대체합니다 ~~. (텍스트 내부에 없는 것으로 알려진 것을 사용했습니다.)
  2. 나머지 따옴표를 모두 큰따옴표로 바꿉니다.
  3. 모든 내부 ~~{...}~~시퀀스를 다음으로 대체하십시오.~~"{...}"~~
  4. 모든 ~~~~시퀀스(모든 내부 시퀀스)를 다음으로 대체합니다.|
  5. 나머지 모든 ~~시퀀스 제거(줄의 시작과 끝 부분)

각 단계가 실행되고 다음 테스트 텍스트가 제공됩니다.

"164829" | "collection 1" | "wood plank 2" x 4" long" | "23.5"
"939485"|"collect "name""|"more items with | " and ""|"294.5""

각 단계 후에 다음과 같은 출력을 얻습니다.

$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;' testinput.txt                       
~~164829~~~~collection 1~~~~wood plank 2" x 4" long~~~~23.5~~
~~939485~~~~collect "name"~~~~more items with | " and "~~~~294.5"~~

$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;' testinput.txt
~~164829~~~~collection 1~~~~wood plank 2"" x 4"" long~~~~23.5~~
~~939485~~~~collect ""name""~~~~more items with | "" and ""~~~~294.5""~~

$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;' testinput.txt
~~"164829"~~~~"collection 1"~~~~"wood plank 2"" x 4"" long"~~~~"23.5"~~
~~"939485"~~~~"collect ""name"""~~~~"more items with | "" and """~~~~"294.5"""~~

$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;' testinput.txt
~~"164829"|"collection 1"|"wood plank 2"" x 4"" long"|"23.5"~~
~~"939485"|"collect ""name"""|"more items with | "" and """|"294.5"""~~

$ perl -pe 's/(?:(?:\||^)[ ]*"(.*?)\"[ ]*(?=\||$))/~~\1~~/gm;s/"/""/g;s/~~(.*?)~~/~~"\1"~~/g;s/~~~~/|/g;s/~~//g' testpipe.txt
"164829"|"collection 1"|"wood plank 2"" x 4"" long"|"23.5"
"939485"|"collect ""name"""|"more items with | "" and """|"294.5"""

답변2

큰따옴표는 실제 큰따옴표(" vs ")가 아닙니다.
실제 큰따옴표 "를 사용하면 sed로 이를 시도해 볼 수 있습니다(데이터에 @가 없다고 가정).

sed 's/" | "/@/g;s/"/""/g;s/^"//;s/"$//;s/@/" | "/g' infile

답변3

이 포럼의 Bahrat는 문제 해결에 매우 가까운 답변을 게시했지만 어떻게든 이 게시물에서 삭제되었습니다(아래 코드). 유일한 문제는 문자열의 파이프를 처리할 수 없다는 것입니다(예: "25" | "데이터를 연결하려면 하나를 사용해야 합니다" | "부록 1" | 20 | "마지막 항목"). 그는 오늘 게시하기로 되어 있었지만 그 스레드가 삭제됐나요?

awk -v FS='|' -v OFS='|' '{for(i=1;i<=NF;i++){gsub(/"/,"\"\"",$i);sub(/"/,"",$i);sub(/"[^"]*$/,"",$i)}print}' myfile > myfile3

답변4

입력 -

"2017"|"S"|"221318"|"우리"|"20170118"|"누군가의 이름"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536" |" 00090"|"Local00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|""|""|""|""|"005"| "00000000" |" "|" "|"1785"|"50228"|"R"|"2017"|"NMT NOTE| 5" X 3" NAT ON BLK"|" "|" "|"USD"| |" "|"000"|"코인"|"04"|35.00|"00"

주문하다:

  awk -v RS='[[:blank:]]*[[:blank:]]*[|][[:blank:]]*|[[:blank:]]*[\n][[:blank:]]*' '{ if ($0 !~ /(^"([^"]|"")*"$)/) { gsub(/\"/,"\"\"");sub(/^"/,"");sub(/"$/,"") } printf "%s%s", $0, RT}' file.txt

출력 -

"2017"|"S"|"221318"|"우리"|"20170118"|"누군가의 이름"|"20170215"|"1785"|"009"|"20170215"|"182339"|"99536" |" 00090"|"Local00"|"930N"|"2017"|"6100"|"0000880"|1.000|0.000|"EA"|""|""|""|""|"005"| "00000000" |" "|" "|"1785"|"50228"|"R"|"2017"|"NMT NOTE| 5"" X 3"" NAT ON BLK"|" "|" "|"USD "|" 7444"|""|"000"|"코인"|"04"|35.00|"00"

관련 정보