.html
フォルダ内のすべてのファイルを見つけて、[file](./file.html)
次のコマンドをindex.md
試しました。
ls | awk "/\.html$/" | xargs -0 -I @@ -L 1 sh -c 'echo "[${@@%.*}](./@@)" >> index.md'
@@
しかし、コマンド内では変更できませんか?私は何が間違っていましたか?
注:ファイル名には、スペースなどの有効な文字を含めることができます。
言う:
index.md
各行のファイルは[file](./file.html)
フォルダの実際のファイル名です。
答え1
ただし:
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
使用するMarkdown構文によっては、次のものが必要になる場合があります。タイトルファイル名に問題のある文字が含まれている場合、URI部分はURIでエンコードされます。そうしないと、状況によってはXSSの脆弱性が発生する可能性があります。 ksh93では、次のことができます。
for f in *.html; do
title=${ printf %H "${file%.*}"; }
title=${title//$'\n'/"<br/>"}
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:<br/>:g;
print "[$_]($uri)"
}'
<br/>
改行文字に使用されます。代わりに、を使用するか、より一般的に印刷できない文字の代替表現形式を選択することもできます。
コードにいくつかのエラーがあります。
- 出力の解析
ls
- 二重引用符の中に
$
リテラルaを使用してください。 - できる
awk
ことに使用されますgrep
(それ自体は間違っていませんが、あまりにも遠くに行く場合)。 xargs -0
入力がNULで区切られていない場合に使用されます。-I
紛争で-L 1
。-L 1
各入力行に対して1つのコマンドを実行しますが、行の各単語は別々の引数として渡されますが、各入力行に対して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
- NULで区切られた出力を取得するには、
ls
次のように置き換えます。printf '%s\0' *
awk
(GNU拡張)を使用したgrep -z
NUL区切り出力の処理xargs -r0
-n
(GNU拡張) //なしで-L
、-I
生成するときにsh
できるだけ多くのファイルを処理させることができるからです。xargs
に渡された単語追加パラメータsh
(位置パラメータインラインコード内)、コードパラメータは私ではありません。- つまり、変数に保存しやすくなるため(デフォルトでは
for file do
位置引数が繰り返されます)、引数${param%pattern}
拡散演算子を使用できます。 printf
代わりに使用してくださいecho
。
言うまでもなく、上記の例のようにfor
ファイルを直接繰り返すのではなく、これを使用することは意味がありません。*.html
1 しかし、私のksh93バージョン(GNUシステムのksh93u +)では、マルチバイト文字を正しく処理できないようです。
答え2
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
本当に必要ですかxargs
?
ls *.html | perl -pe 's/.html\n//;$_="[$_](./$_.html)\n"'
(ファイルが100,000以上の場合):
printf "%s\n" *.html | perl -pe 's/.html\n//;$_="[$_](./$_.html)\n"'
または(遅いが短い):
for f in *.html; do echo "[${f%.*}](./$f)"; done