Bash

為給定文件 F 的每一行 L 執行特定命令 C 然後移動 C(L) 未成功執行的每個 L 的干淨方法是什麼?

  • May 15, 2022

比如說

https://example.nosuchtld
https://example.net
https://example.org
https://example.willfail

是 的內容urls.txt。我想<command> <url>為每個 URL/行執行urls.txt-<command>比方說curl,所以,

cat urls.txt | xargs -n1 curl

或者

<urls.txt xargs -n1 curl

例如。我希望每個未成功curl編輯的 URL/行(所以,第一個和最後一個)

  1. 被刪除urls.txt;和
  2. 被附加到另一個文件——比方說nope.txt——如果它不存在則被創建

離開urls.txt_

https://example.net
https://example.org

並且nope.txt作為

https://example.nosuchtld
https://example.willfail

我知道 shell 執行的每個命令的退出狀態都可以通過變數 獲得$?,它0代表命令的成功執行,而所有其他整數都代表失敗。不過,我不確定如何建構一個包含此命令的複合命令,從正在讀取的文件中刪除行,並將它們附加到不同的文件中。

使用 zsh,您可以執行以下操作:

while IFS= read -ru3 url; do
 curl -- $url
 print -ru $(( $? ? 4 : 5 )) -- $url
done 3< urls 4> bad 5> good

這樣,badandgood文件只打開一次,並且只有當urls它本身可以打開以供閱讀時。

使用bash,您可以循環獲取 url 並測試curl命令,--fail選項curl似乎很適合在腳本中使用,請參閱: 如何檢查 curl 等命令是否完成且沒有錯誤

所以它可能是這樣的:

while read -r url; do
   curl -f "$url" && outputfile='success.txt' || outputfile='nope.txt'
   printf "%s\n" "$url" >> "$outputfile"
done < urls.txt

並用成功的網址覆蓋您的文件。

mv success.txt urls.txt

或用於mapfile將行放入數組中:

mapfile -t urls < urls.txt

for url in "${urls[@]}"; do
   curl -f "$url" && outputfile='success.txt' || outputfile='nope.txt'
   printf "%s\n" "$url" >> "$outputfile"
done

請注意,網址沒有空格。如果您需要執行參數為整行且包含任何字元的命令,那麼這篇文章對如何閱讀每一行很有用:了解“IFS= read -r line”

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