꼬리를 다듬고 쉘의 선행 숫자에 추가하십시오.

꼬리를 다듬고 쉘의 선행 숫자에 추가하십시오.

숫자가 큰따옴표로 묶이고 일부는 묶이지 않은 CSV 파일이 있습니다. 숫자의 음수 기호만 수정해야 했습니다. 뒤에 오는 음수 기호를 제거하고 시작 부분에 추가해야 했습니다.

입력 예:

column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

예제 출력:

column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787

답변1

암소 비슷한 일종의 영양awk해결책:

awk -v FPAT='[^,"]+|"[^"]+"' '
       NR==1; NR>1{ 
           for (i=1; i<=NF; i++) { 
               if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/) { 
                   sub(/-/, "", $i); 
                   sub(/[0-9]/, "-&", $i); 
               } 
               printf "%s%s",$i,(i==NF? ORS:",") 
           } 
       }' file.csv
  • -v FPAT='[^,"]+|"[^"]+"'- 필드 값을 정의하는 정규식 패턴
  • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/- 필드에 숫자와 빼기 기호가 포함되어 있는지 확인하세요 -(숫자는 큰따옴표로 묶을 수 있음).

산출:

column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787

답변2

CSV 데이터에는 CSV 파서가 필요합니다. 루비에는 다음이 하나 있습니다:

$ cat file.csv
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

$ ruby -rcsv -e '
    CSV.foreach(ARGV.shift) do |row|
        corrected = row.collect {|e| e.sub(/^([\d,.]+)-$/, "-\\1")}
        puts CSV.generate_line(corrected)
    end
' file.csv
-12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787

CSV 생성기는 "인용된 문자열"에 쉼표가 포함되어 있지 않기 때문에 인용할 필요가 없다고 결정했습니다.

답변3

FPAT가 없는 gawkAwk 솔루션 :

NR==1;

NR > 1 {
    $0 = $0","

    while ($0) {
        match($0, / *"[^"]*" *,|[^,]*,/)
        f = substr($0,RSTART,RLENGTH-1)             # save what matched in f
        if (( f ~ /^"[0-9]([0-9,.]+[0-9]+)-"$/ ) ||
            ( f ~ /^[0-9]+[.]?[0-9]+-$/ ) ||
            ( f ~ /^[0-9]+-$/ )) {
            sub(/-/, "", f);
            sub(/[0-9]/, "-&", f);
        }
        $0 = substr($0, RLENGTH+1)                 
        printf "%s%s", f, (0 == NF ? "\n" : ",")
    }
}

제공된 예제 파일의 출력은 다음과 같습니다.

column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787

답변4

sed지원되는 구현 에서는 문자열 필드에 포함된 큰따옴표가 다음과 같이 인코딩되고 이러한 문자열 필드에 줄바꿈이 포함되지 않는 것으로 -E가정됩니다 .""

sed -E '
  :1
  s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/\1-\3\4/;
  s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/\1"-\3"\4/
  t1' < file

입력의 성격에 따라 숫자를 더 엄격하게 일치시킬 수 있습니다. 예를 들어, ([0-9.]+)-여기서는 on과 일치 12-하지만 와도 일치합니다 ...-. 해당 유형의 입력이 입력에 나타날 가능성이 있는 경우 이를 ([0-9]*\.?[0-9]+)-다음과 같이 변경할 수 있습니다.

관련 정보