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

Не анализировать ls .
Вам не нужно xargsдля этого, вы можете использовать find -exec.

попробуй это,

find. -maxdepth 1 -type f -name "*.html" -exec \
    sh -c 'f=$(basename "$1"); echo "[${f%.*}]($1)" >> index.md' sh {} \;

Если вы хотите, чтобы использовал xargs, используйте очень похожую версию:

find. -maxdepth 1 -type f -name "*.html" -print0 | \
    xargs -0 -I{} sh -c 'f=$(basename "$1"); echo "[${f%.*}]($1)" >> index.md' sh {} \;

Другой способ без запуска xargsили-exec:

find. -maxdepth 1 -type f -name "*.html" -printf '[%f](./%f)\n' \
    | sed 's/\.html\]/]/' \
    > index.md

3
05.06.2021, 11:54
7 ответов

Использованиеawk:

awk 'BEGIN{FS="|"; OFS=","; dq="\042"}
{for(i=1;i<=NF;i++) if ($i ~ /,/)$i = dq $i dq;}1' file                                                                                                          

Прежде всего, разделитель полей(FS)и разделитель выходных полей(OFS)устанавливаются на |и ,соответственно. Новая переменная dqзаключена в двойные кавычки(\042)в правиле BEGIN.

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

Если вы хотите заключать в кавычки все, кроме цифр, то подойдет следующее.

awk 'BEGIN{FS="|"; OFS=","; dq="\042"}
{for(i=1;i<=NF;i++) if ($i+0 != $i)$i = dq $i dq;}1' file
2
28.07.2021, 11:26

Вы могли бы сделать:

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

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

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

3
28.07.2021, 11:26

Используя 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 и т. д., нет причин или использовать синтаксический анализатор для этого формата документа для синтаксического анализа. этот документ.

14
28.07.2021, 11:26

С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используется для объединения полей с символом ,.

3
28.07.2021, 11:26

Другой 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и избежать утомительной работы по экранированию

0
28.07.2021, 11:26

Идея, аналогичная предложенной @Kusalananda :, использовать специализированный инструмент для анализа CSV. Это рубиновый пример:

ruby -rcsv -e 'CSV.foreach(ARGV.shift, col_sep: "|") {|row| puts CSV.generate_line row}' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
0
28.07.2021, 11:26
awk -F "|" 'OFS="|" {print $1,"\""$2"\"",$3}' filename

выход

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4
0
28.07.2021, 11:26

Теги

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