Bash
為給定文件 F 的每一行 L 執行特定命令 C 然後移動 C(L) 未成功執行的每個 L 的干淨方法是什麼?
比如說
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/行(所以,第一個和最後一個)
- 被刪除
urls.txt
;和- 被附加到另一個文件——比方說
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
這樣,
bad
andgood
文件只打開一次,並且只有當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”