Awk

Xargs 提取文件名

  • September 5, 2018

我想找到.html一個文件夾中的所有文件並附[file](./file.html)加到另一個名為index.md. 我嘗試了以下命令:

ls | awk "/\.html$/" | xargs -0 -I @@ -L 1 sh -c 'echo "[${@@%.*}](./@@)" >> index.md'

但它不能@@在命令內部替代?我究竟做錯了什麼?

注意:文件名可以包含空格等有效字元


澄清:

index.md每一行都有[file](./file.html)where file 是文件夾中的實際文件名

做就是了:

for f in *.html; do printf '%s\n' "[${f%.*}](./$f)"; done > index.md

當沒有文件時,使用set -o nullglob( zsh, yash) 或shopt -s nullglob( bash) for*.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 編碼,並對 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

HTML 編碼和 URI 編碼在哪裡%H¹ %#H,但我們仍然需要分別處理換行符。

或與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是每行輸入執行一個命令,但將行中的每個單詞作為單獨的參數傳遞,同時-I @@為每一行輸入執行一個命令,用整行(減去尾隨空格,並且引用仍在處理)用於替換@@
  • {}在(命令注入漏洞)的程式碼參數中使用sh
  • in shvarin${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
  • 替換lsprintf '%s\0' *以獲取 NUL 分隔的輸出
  • awk使用grep -z(GNU 擴展)來處理 NUL 分隔的輸出
  • xargs -r0(GNU 擴展)沒有任何-n// -L-I因為當我們生成 ash時,我們不妨讓它處理盡可能多的文件
  • 已將xargs單詞作為額外參數傳遞給sh(成為內聯程式碼內的位置參數),而不是在程式碼參數內。
  • 這意味著我們可以更輕鬆地將它們儲存在變數中(這裡for file do預設情況下使用 which 循環位置參數),因此我們可以使用${param%pattern}參數擴展運算符。
  • 使用printf而不是echo.

不用說,使用它而不是像上面範例中那樣for直接在文件上進行循環是沒有意義的。*.html


¹它似乎不適用於我的 ksh93 版本中的多字節字元(GNU 系統上的 ksh93u+)

引用自:https://unix.stackexchange.com/questions/466550