[英]Bash: While-read loop skips the last line of comma-separated text file
[英]How can I loop over comma-separated lists *inside* each line of a file?
需要在bash脚本中编写一些状态检查器:
有这样的字符串文件:
domain.com; 111.111.111.111,222.222.222.222; /link/to/somefile.js,/link/to/somefile2.js
domain2.com; 122.122.111.111,211.211.222.222; /link/to/somefile2.js,/link/to/somefile3.js
总共需要执行以下命令:
curl -s -I -H 'Host: domain.com' http://111.111.111.111/link/to/somefile.js
curl -s -I -H 'Host: domain.com' http://222.222.222.222/link/to/somefile.js
curl -s -I -H 'Host: domain.com' http://111.111.111.111/link/to/somefile2.js
curl -s -I -H 'Host: domain.com' http://222.222.222.222/link/to/somefile2.js
curl -s -I -H 'Host: domain2.com' http://122.122.111.111/link/to/somefile2.js
curl -s -I -H 'Host: domain2.com' http://211.211.222.222/link/to/somefile2.js
curl -s -I -H 'Host: domain2.com' http://122.122.111.111/link/to/somefile3.js
curl -s -I -H 'Host: domain2.com' http://211.211.222.222/link/to/somefile3.js
问题是:
xargs
可以做到这一点或gnu parallel
吗? 我可以分隔行并将结果设置为不同的变量,这根本不是问题:
domain=$(cut -d';' -f1 file| xargs -I N -d "," echo curl -H) \'N\'
ip=$(cut -d';' -f2 file| xargs -I N -d "," echo curl -H) \'N\'
and else
但是,另一个问题是:):在将字符串分隔和分隔为变量之后,在那种情况下如何使用不同的变量执行curl-不同变量的参数数量会有所不同?
得到Barmar的答案根本不涉及任务问题,因为它的列表大于两个。 问题不在于bash的无知,而是我可以解决的问题
#!/usr/bin/env bash
# ^^^^- IMPORTANT: not /bin/sh
# print command instead of running it, so people can test their answers without real URLs
log_command() { printf '%q ' "$@"; printf '\n'; }
while IFS='; ' read -r domain addrs_str files_str; do
IFS=, read -a addrs <<<"$addrs_str"
IFS=, read -a files <<<"$files_str"
for file in "${files[@]}"; do
for addr in "${addrs[@]}"; do
log_command curl -s -I -H "Host: $domain" "http://$addr/$file"
done
done
done
...作为输出发出(作为命令列表,如果删除了log_command
前缀则将运行):
curl -s -I -H Host:\ domain.com http://111.111.111.111//link/to/somefile.js
curl -s -I -H Host:\ domain.com http://222.222.222.222//link/to/somefile.js
curl -s -I -H Host:\ domain.com http://111.111.111.111//link/to/somefile2.js
curl -s -I -H Host:\ domain.com http://222.222.222.222//link/to/somefile2.js
curl -s -I -H Host:\ domain2.com http://122.122.111.111//link/to/somefile2.js
curl -s -I -H Host:\ domain2.com http://211.211.222.222//link/to/somefile2.js
curl -s -I -H Host:\ domain2.com http://122.122.111.111//link/to/somefile3.js
curl -s -I -H Host:\ domain2.com http://211.211.222.222//link/to/somefile3.js
...您可以在https://ideone.com/dTC8q8上看到
现在如何运作?
步骤1:将每一行读入domain
, addrs_str
和files_str
,以分号和空格分隔。
这是通过IFS='; ' read -r domain addrs_str files_str
行完成IFS='; ' read -r domain addrs_str files_str
IFS='; ' read -r domain addrs_str files_str
,其运行方式如BashFAQ#1和如何从文件中读取变量中所述,每行有多个变量?
addrs_str
和files_str
,将它们以逗号分隔为单独的数组。 如何在Bash中的定界符上分割字符串中对此进行了说明? curl
。 如果只想用第一个文件调用第一个IP,用第二个文件调用第二个IP,则可以在bash中同时对两个数组使用Iterate 。 否则,这是一个简单的嵌套循环。 使用GNU Parallel,它看起来像这样
doit() {
domain="$1"
ips="$2"
paths="$3"
parallel --dry-run -d ',' -q curl -s -I -H Host:\ "$domain" http://{1}/{2} ::: "$ips" ::: "$paths"
}
export -f doit
parallel --colsep ';' doit :::: input.file
当您确信--dry-run
时,将其删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.