Просто сделай:
for f in *.html; do printf '%s\n' "[${f%.*}](./$f)"; done > index.md
Используйте set -o nullglob
(zsh
,yash
)илиshopt -s nullglob
(bash
)для *.html
, чтобы раскрыть ничего вместо*.html
(или сообщить об ошибке в zsh
), когда нет html
файла. С zsh
вы также можете использовать *.html(N)
или в ksh93
~(N)*.html
.
Или одним printf
звонком сzsh
:
files=(*.html)
rootnames=(${files:r})
printf '[%s](./%s)\n' ${basenames:^files} > index.md
Обратите внимание, что в зависимости от используемого синтаксиса уценки вам может потребоваться HTML -кодировать часть title , а URI -кодировать часть URI, если имена файлов содержат некоторые проблемные персонажи. Несоблюдение этого требования может даже привести к появлению формы уязвимости XSS в зависимости от контекста. с кш93,вы можете сделать это с помощью:
for f in *.html; do
title=${ printf %H "${file%.*}"; }
title=${title//$'\n'/"
"}
uri=${ printf '%#H' "$file"; }
uri=${uri//$'\n'/%0A}
printf '%s\n' "[$title]($uri)"
done > index.md
Где %H
¹ определяет кодировку HTML, а %#H
кодировку URI, но нам по-прежнему нужно обращаться к символам новой строки отдельно.
Или сperl
:
perl -MURI::Encode=uri_encode -MHTML::Entities -CLSA -le '
for (<*.html>) {
$uri = uri_encode("./$_");
s/\.html\z//;
$_ = encode_entities $_;
s:\n:
:g;
print "[$_]($uri)"
}'
Использование
для символов новой строки. Вместо этого вы можете использовать  или, в более общем случае, выбрать какую-либо форму альтернативного представления для непечатаемых символов -.
В вашем коде есть несколько ошибок:
ls
$
как литерал внутри двойных кавычек awk
для чего-то, что grep
может сделать (само по себе не неправильно, но излишне)xargs -0
, когда ввод не является NUL -разделителем -I
конфликтует с -L 1
. -L 1
запускает одну команду на строку ввода, но каждое слово в строке передается как отдельные аргументы, тогда как -I @@
запускает одну команду для каждой строки ввода с полной строкой (за вычетом завершающих пробелов и заключением в кавычки. все еще обрабатывается )используется для замены @@
. {}
внутри кода аргументаsh
(уязвимость внедрения команд)sh
var
в ${var%.*}
— это имя переменной , оно не будет работать с произвольным текстом. echo
для произвольных данных. Если вы хотите использовать xargs -0
, вам понадобится что-то вроде:
printf '%s\0' * | grep -z '\.html$' | xargs -r0 sh -c '
for file do
printf "%s\n" "[${file%.*}](./$file)"
done' sh > file.md
ls
на printf '%s\0' *
для получения вывода с разделителями NUL -awk
сgrep -z
(расширением GNU )для обработки этого вывода с разделителями NUL -xargs -r0
(Расширения GNU )без каких-либо -n
/ -L
/ -I
, потому что, пока мы создаем sh
, мы могли бы также обработать как можно больше файлов xargs
передать слова в качестве дополнительных аргументов в sh
(, которые становятся позиционными параметрами внутри встроенного кода ),не внутри аргумента кода. for file do
, который по умолчанию перебирает позиционные параметры ), поэтому мы можем использовать оператор раскрытия параметров ${param%pattern}
. printf
вместо echo
. Само собой разумеется, что нет особого смысла использовать это вместо того, чтобы выполнять этот цикл for
непосредственно над файлами *.html
, как в верхнем примере.
¹ Кажется, он не работает должным образом для многобайтовых символов в моей версии ksh93, хотя (ksh93u+ в системе GNU)
Если он не установлен в вашей личной среде, он устанавливается для каждого пользователя. Это означает, что где-то под /etc
. Перейдите к /etc
и введите:
grep usr.games * */* */*/* 2> /dev/null
При установке Ubuntu это даст вам:
environment:PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
login.defs:ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
manpath.config:MANPATH_MAP /usr/games /usr/share/man
passwd:games:x:5:60:games:/usr/games:/usr/sbin/nologin
passwd-:games:x:5:60:games:/usr/games:/usr/sbin/nologin
Файлы passwd
предназначены для пользовательских игр, поэтому не имеют значения. manpath
предназначен для чтения руководств. Итак, если вы удалите его из environment
и login.defs
, ваши игровые -дни закончились.
Его можно установить в нескольких местах. Для начала его можно установить одним или несколькими из следующих:
~/.bashrc
, /etc/profile
, /etc/bash.bashrc
, /etc/profile.d/*
и т. д.)/etc/login.defs
/etc/security/pam_env.conf
/etc/environment
$HOME/.pam_environment