Не анализировать 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
Использование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
Вы могли бы сделать:
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-файла.
Используя 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 и т. д., нет причин или использовать синтаксический анализатор для этого формата документа для синтаксического анализа. этот документ.
С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
используется для объединения полей с символом ,
.
Другой 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
и избежать утомительной работы по экранированию
Идея, аналогичная предложенной @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
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