比如说
https://example.nosuchtld
https://example.net
https://example.org
https://example.willfail
是 的内容urls.txt
。我想运行-where<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
变量表示命令的成功执行,而所有其他整数表示失败。不过,我不确定如何构建一个包含此命令的复合命令,从正在读取的文件中删除行,并将它们附加到另一个文件中。
答案1
使用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
请注意,url 中没有空格。如果您需要执行一个命令,其中参数是带有任何字符的整行,那么这篇文章对于如何读取每一行很有用:理解“IFS=读取-r行”
答案2
使用 zsh,你可以这样做:
while IFS= read -ru3 url; do
curl -- $url
print -ru $(( $? ? 4 : 5 )) -- $url
done 3< urls 4> bad 5> good
这样,bad
和good
文件仅被打开一次,并且仅当urls
其本身可以打开以供读取时。