Игнорирование экранированных разделителей (запятых) с помощью awk?

StackOverflow https://stackoverflow.com/questions/1468210

  •  13-09-2019
  •  | 
  •  

Вопрос

Если бы у меня была строка с экранированными запятыми, например, так:

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

Как я мог бы использовать awk для разбора этого на следующие элементы?

a
b
{c\,d\,e}
f
g
Это было полезно?

Решение

{
   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. Построить массив b От a, объединяя строки , которые заканчиваются на '\'
  3. Печать массива b (Примечание:Начинается с 2, так как первый элемент пуст)

Это решение предполагает (на данный момент), что ',' это единственный символ , который когда - либо экранировался с помощью '\'- то есть, нет необходимости обрабатывать какие-либо \\ во входных данных, ни странных комбинаций, таких как \\\,\\,\\\\,,\,.

Другие советы

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

Я не думаю, что 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")
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top