1

awkを使用して達成しようとしているこのbash行について、少しアドバイス/ヘルプが必要です。

基本的に、次のようにコンマ区切りの値を保持する変数があります。

"abc,abd,abf,abz,abz"

各フィールドの取得は、単純な awk ループで非常に簡単です

echo ${var} | awk -F"," '{for(i=1;i<=NF;i++){print $i}}'

問題は、これらのカンマ区切りの値に、途中にカンマがある文字列が含まれている場合があることです。たとえば、次のようになります。

"abc,"abd,abf,abz",abh,abr,alk"

この場合、「abd、abf、abz」は単一の値です。引用符の間の内容は完全な値として扱われ、区切られないようにする必要があることを awk に伝える必要がありますが、どこにも行きません。何かアドバイスはありますか?

4

4 に答える 4

1

サンプル入力に表示されている最初/最後の二重引用符が実際には入力に存在しない場合:

$ echo 'abc,"abd,abf,abz",abh,abr,alk' |
awk -F\" '{
    for (i=1;i<=NF;i++) {
        if (i%2) {
            gsub(/^,|,$/,"",$i)
            nf = split($i,a,/,/)
            for (j=1; j<=nf; j++) {
                print a[j]
            }
        }
        else {
            print $i
        }
    }
}'
abc
abd,abf,abz
abh
abr
alk

それらが存在する場合:

$ echo '"abc,"abd,abf,abz",abh,abr,alk"' |
awk -F\" '{
    for (i=2;i<NF;i++) {
        if ( !(i%2) ) {
            gsub(/^,|,$/,"",$i)
            nf = split($i,a,/,/)
            for (j=1; j<=nf; j++) {
                print a[j]
            }
        }
        else {
            print $i
        }
    }
}'
abc
abd,abf,abz
abh
abr
alk
于 2013-03-26T14:47:53.370 に答える
1

私がawkでできる最善のこと:

$ echo 'abc,"xxx,yyy,zzz",abh,abr,alk' | awk -F'"' '{
    for(i=1;i<=NF;i++) {
      if (i %2 == 0) {
        printf "\""$i"\"";
      } else {
        n=split($i,array,",");
        for (j=1; j<n; j++) {
          print array[j];
        }
      }
    }
  }'
abc
"xxx,yyy,zzz"
abh
abr
alk

ただし、これにより空の行が表示されます:(、私はまだ理由を見つけようとしています。

更新: 固定 + インデント

于 2013-03-26T14:24:40.197 に答える
1

まず、最初の例ではループする必要はまったくありません。

$ awk '{print}' RS=',' <<< 'abc,abd,abf,abz,abz'
abc
abd
abf
abz
abz

2 番目の例では、適切な CSV パーサーが本当に必要です。ここにpython解決策があります:

#!/usr/bin/env python
from csv import reader, writer
from sys import stdin, stdout
writer(stdout, delimiter='\n').writerows(reader(stdin))

デモ:

$ cat file
abc,"abd,abf,abz",abh,abr,alk

$ csv_delimiter.py < file 
abc
abd,abf,abz
abh
abr
alk
于 2013-03-26T14:25:32.963 に答える