用awk忽略转义的分隔符(逗号)?

时间:2009-09-23 19:53:21

标签: awk delimiter escaping

如果我有一个带有转义逗号的字符串,请执行以下操作:

a,b,{c\,d\,e},f,g

我如何使用awk将其解析为以下项目?

a
b
{c\,d\,e}
f
g

3 个答案:

答案 0 :(得分:2)

{
  gsub("\\\\,", "!Q!")
  n = split($0, a, ",")
  for (i = 1; i <= n; ++i) {
    gsub("!Q!", "\\,", a[i])
    print a[i]
  }
}

答案 1 :(得分:2)

{
   split($0, a, /,/)
   j=1
   for(i=1; i<=length(a); ++i) {
      if(match(b[j], /\\$/)) {
         b[j]=b[j] "," a[i]
      } else {
         b[++j] = a[i]
      }
   }
   for(k=2; k<=length(b); ++k) {
      print b[k]
   }
}
  1. 使用“a”作为分隔符
  2. 拆分为数组,
  3. b构建数组a,合并以“\”结尾的行
  4. 打印数组b(注意:由于第一项为空白,所以从2开始)
  5. 此解决方案假设(目前)“,”是唯一使用“\”进行转义的字符 - 也就是说,无需处理任何\\在输入中,也不是奇怪的组合,例如\\\,\\,\\\\,,\,

答案 2 :(得分:1)

我不认为awk对此类内容有任何内置支持。这里的解决方案并不像DigitalRoss那么短,但应该没有意外碰到你的伪造字符串的危险(!Q!)。由于它使用if进行测试,您还可以对其进行扩展,以确保在字符串末尾是否确实有\\,,这应该是转义斜杠,而不是逗号。

BEGIN {
    FS = ","
}

{
    curfield=1
    for (i=1; i<=NF; i++) {
        if (substr($i,length($i)) == "\\") {
            fields[curfield] = fields[curfield] substr($i,1,length($i)-1) FS
        } else {
            fields[curfield] = fields[curfield] $i
            curfield++
        }
    }
    nf = curfield - 1
    for (i=1; i<=nf; i++) {
        printf("%d: %s   ",i,fields[i])
    }
    printf("\n")
}