특정 문자열 사이에서 따옴표를 찾아 추가하세요.

특정 문자열 사이에서 따옴표를 찾아 추가하세요.

csv로 작업할 때 원치 않는 쉼표(',')가 내 csv 파일을 오해하게 만들어 결과적으로 불일치가 발생합니다.

아래에서 자세히 알아보세요.

내 샘플 CSV 파일:

1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4

나는 다음과 같은 최종 결과를 원합니다.

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4

따옴표를 추가한 후 "|"를 바꾸겠습니다. 내 CSV가 예상대로 작동하도록 ","를 사용합니다.

아래 명령을 사용했지만 예상대로 제공되지 않습니다.

sed -e 's/,/"&"/' file1.txt

답변1

csvformat에서 사용csvkit, 최종 결과는 쉼표를 구분 기호로 사용하는 CSV 파일이어야 한다고 가정합니다(질문 텍스트에 설명된 대로).

$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4

|이렇게 하면 -문자를 구분 기호로 사용하는 것에서 기본 쉼표를 구분 기호로 사용하도록 CSV 파일의 형식을 다시 지정합니다 . 이렇게 하면 인용이 필요한 필드를 적절하게 인용합니다.

이는 또한 개행 문자가 포함된 필드를 적절하게 처리합니다.

$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5

CSV, JSON, XML, YAML, TOML 등과 같은 구조화된 문서 형식의 문서가 있는 경우에는 이유가 없습니다.~ 아니다해당 문서 형식에 대한 파서를 사용하여 해당 문서를 구문 분석합니다.

답변2

당신은 할 수 있습니다 :

awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile

-F'[|]'입력 필드 구분 기호를 정의했습니다 . 출력 파일 구분 기호를 정의했습니다
. FS(입력 필드 구분 기호)를 기반으로 각 라인/레코드에 필드가 몇 개 있는지 식별하므로 필드 수를 반복하고 각 필드에 큰따옴표를 추가한 다음 라인에 최종 업데이트를 인쇄합니다.-v OFS=','
NFawk의 1관용구인쇄용.

모든 필드는 이 명령으로 인용되며 이는 분명히 유효한 CSV 파일을 갖는 데에는 문제가 되지 않습니다.

답변3

와 함께 sed:

$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
  • s/[^|]*,[^|]*/"&"/g다음을 포함하는 모든 필드에 큰따옴표를 추가하세요.,
  • y/|/,/모든 |문자를 다음으로 변경,

와 함께 perl:

perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'

이는 |입력 필드 구분 기호로 사용됩니다. 그런 다음 map포함된 모든 필드에 큰따옴표를 추가합니다 ,. 마지막으로 join필드를 ,문자와 결합하는 데 사용됩니다.

답변4

또 다른 sed방법:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

또는 와 같은 sed로드를 지원하는 경우 모든 이스케이프 작업을 피할 수 있습니다.EREGNU sed

  sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data

|각 경계에서 중간 그룹만 a로 구분된다는 사실을 활용하여 sed더 짧게 만들 수 있습니다.

sed 's;|\([^|]*\)|;,"\1",;' data

물론 여기에서도 sed를 지원한다면 지루한 탈출 작업을 -E로드하고 피할 수 있습니다.ERE

관련 정보