Найти и добавить кавычки между определенными строками

Найти и добавить кавычки между определенными строками

Когда я работаю с CSV, нежелательные запятые (',') вводят мой CSV-файл в заблуждение, в результате чего возникает несоответствие.

Подробную информацию вы найдете ниже.

Мой пример CSV-файла:

1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4

Я хочу получить конечный результат:

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4

После добавления кавычек я заменю «|» на «,», чтобы мой CSV-файл работал так, как я и ожидал.

Я использовал команду ниже, но она не дала ожидаемого результата.

sed -e 's/,/"&"/' file1.txt

решение1

Используя csvformatизcsvkitи предполагая, что конечным результатом должен быть CSV-файл с запятой в качестве разделителя (как описано в тексте вопроса):

$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4

Это переформатирует CSV-файл с |-символов в качестве разделителя на запятую по умолчанию. При этом поля, которые нужно закавычить, будут правильно заключены в кавычки.

Это также правильно обрабатывает поля со встроенными символами новой строки:

$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5

Если у вас есть документ в каком-либо структурированном формате, например CSV, JSON, XML, YAML, TOML и т. д., то нет причиннетиспользовать анализатор для данного формата документа, чтобы проанализировать этот документ.

решение2

Вы можете сделать:

awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile

с -F'[|]'мы определили разделитель входных полей.
с -v OFS=','мы определили разделитель выходных полей.
NFопределяет, сколько полей содержится в каждой строке/записи на основе FS (разделитель входных полей), поэтому мы перебираем количество полей и добавляем двойные кавычки для каждого из них и печатаем окончательное обновление в строке с1идиома awkдля печати.

обратите внимание, что при использовании этой команды все поля заключаются в кавычки, что, очевидно, не является проблемой для корректного файла CSV.

решение3

С sed:

$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
  • s/[^|]*,[^|]*/"&"/gдобавьте двойные кавычки ко всем полям, содержащим,
  • y/|/,/изменить все |символы на,

С perl:

perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'

Это используется |как разделитель полей ввода. Затем mapбудут добавлены двойные кавычки для всех полей, содержащих ,. Наконец, joinиспользуется для объединения полей с ,символом.

решение4

Другой sedпуть:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

Или, если вы sedподдерживаете загрузку ERE, например GNU sed, вы можете избежать всех экранирующих заданий:

  sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data

Вы можете воспользоваться тем фактом, что только средняя группа отделена на |каждой границе, и сделать sedеще короче:

sed 's;|\([^|]*\)|;,"\1",;' data

Конечно, и здесь, если ваша поддержка sed, -Eвы можете загрузить EREи избежать утомительной работы по выходу из игры.

Связанный контент