Можно ли с помощью sed поставить двойные кавычки всего в несколько столбцов?

* в шаблонах оболочки соответствует 0 или более символам. Его не следует путать с оператором регулярного выражения * , который означает 0 или более из предыдущего атома .

В базовых шаблонах оболочки нет эквивалента регулярного выражения * . Однако в различных оболочках для этого есть расширения.

  • ksh имеет * (что-то) :

     ls a _ * ([az]) _ data 
     
  • вы можете иметь то же самое в bash с shopt -s extglob или zsh с setopt kshglob :

     shopt -s extglob 
    ls a _ * ([az] ) _data 
     
  • В zsh с включенным extendedglob , # эквивалентно регулярному выражению * :

     setopt extendedglob 
    ls a_ [az] #_ data 
     
  • В последних версиях ksh93 вы также можете использовать регулярные выражения в глобах. Здесь с расширенными регулярными выражениями:

     ls ~ (E: a_ [az] * _ data) 
     

Обратите внимание, что [az] соответствует разным вещам в зависимости от на текущей локали. Обычно он сопоставляет только 26 a - z латинские буквы без акцента в локали C . В других регионах это обычно соответствует большему количеству и не всегда имеет смысл. Чтобы соответствовать букве в вашем языковом стандарте, вы можете предпочесть [[: alpha:]] .

1
12.04.2018, 04:04
5 ответов

Я мог бы подойти к этому с помощью awk таким образом:

  1. установить разделитель полей вывода на то, что является разделителем полей ввода, который мы назначаем как запятую-F,
  2. для каждой строки переназначьте значения полей 1, 5 и 6 как исходные значения, но заключенные в двойные -кавычки. Очевидный беспорядок в кавычках возникает из-за того, что я использовал двойные -кавычки для создания окружающей строки, и поскольку единственная строка, которую я хочу напечатать , — это двойная -кавычка, я должен экранировать ее, поэтому каждый двойная -кавычка, которую я хочу, заканчивается "\"".
  3. Как только поля будут обновлены, напечатайте новую -комбинированную строку.

Скрипт:

awk -F, 'BEGIN{ OFS=FS } {$1="\""$1"\""; $5="\""$5"\""; $6="\""$6"\""; print }' < input.csv > output.csv

Когда вы обнаружите, что вам нужно указать больше полей, просто сделайте то же самое, что и с полями 1, 5 и 6 выше.

2
27.01.2020, 23:12

Если вы действительно хотите использовать sed(, что я не рекомендую, если доступны awkили perl), тогда предположим, что шестой столбец заканчивается строкой, а не запятой И что поля сами по себе не содержат встроенных (кавычек )запятых:

sed -E -e 's/([^,]*),/"\1",/1' -e 's/([^,]*),/"\1",/5' -e 's/([^,]*)$/"\1"/' file
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"

Общий шаблон — s/([^,]*),/"\1",/n, где nотносится к n-му вхождению нуля или более символов, отличных от -,, за которыми следует ,, а \1— это ссылка на захваченный шаблон (в круглых скобках. ).

0
27.01.2020, 23:12

Сperl

$ perl -F, -lane 'map {$_=qq("$_")} @F[0,4,5]; print join ",", @F' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
  • -F,использовать ,в качестве разделителя полей ввода, результаты доступны в массиве @F
  • map {$_=qq("$_")} @F[0,4,5]обязательные элементы массива в двойных кавычках. Индекс начинается с 0. Оператор qqиспользуется здесь, чтобы избежать экранирования двойных кавычек, qq("$_")такой же, как"\"$_\""
  • print join ",", @Fнапечатать измененный массив с ,в качестве разделителя


Другой способ сделать сawk

$ awk -v q='"' 'BEGIN{split("1 5 6",a); FS=OFS=","}
                {for(i in a) $a[i]=q $a[i] q} 1' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
  • -v q='"'сохранить двойную кавычку как значение в переменной q
  • split("1 5 6",a)индекс сохранения будет изменен как значения в aмассиве (по умолчанию разделен на пробелы, FS еще не изменен)
  • FS=OFS=","изменить разделитель ввода/вывода на,
  • for(i in a) $a[i]=q $a[i] qизменить обязательные поля
  • 1идиоматический способ распечатать содержимое$0
1
27.01.2020, 23:12

Использованиеcsvtoolс полезной командой format:

csvtool format '"%1",%2,%3,%4,"%5","%6"\n' file.csv 

Пример:

echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" |
csvtool format '"%1",%2,%3,%4,"%5","%6"\n' -

Выход:

"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"

csvtoolтакже могут callфункции оболочки и внешние программы для разбора строк из файлов.CSV . Чтобы сделать то же самое, используя printf, но выведите «123 » в шестнадцатеричном формате, выполните:

echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" | 
csvtool call "printf '\"%s\",%s,%s,%s,\"%s\",\"%x\"\n'" -

Выход:

"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","7b"
6
27.01.2020, 23:12

Для этого существует простой способ :использовать escape-символ \, когда вы ставите " перед и в конце столбца.

cat test.txt | awk '{ print $1" ""\""$2"\""}'

Попробуйте.

0
26.07.2020, 10:14

Теги

Похожие вопросы