1

我需要一些关于这条 bash 行的建议/帮助,我正在尝试使用 awk 来完成,

基本上,我有一个保存逗号分隔值的变量,如下所示:

"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

对于第二个示例,您确实需要一个合适的 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 回答
0

查看csvtool使您能够操作 CSV 文件的程序。

它可以与apt-get (或任何你的包管理器)一起安装,并在你的 Bash 文件中用于处理 CSV 文件。

于 2017-06-25T07:13:53.637 回答