我正在编写一个脚本,该脚本将.txt
文件名作为参数,逐行读取文件,并将每一行传递给命令。例如,它运行command --option "LINE 1"
、 thencommand --option "LINE 2"
等。命令的输出被写入另一个文件。我该如何去做呢?我不知道从哪里开始。
答案1
另一种选择是xargs
。
使用 GNU xargs
:
xargs -a file -I{} -d'\n' command --option {} other args
{}
是文本行的占位符。
其他xargs
通常没有-a
, -d
,但有些有-0
NUL 分隔输入。有了这些,您可以执行以下操作:
< file tr '\n' '\0' | xargs -0 -I{} command --option {} other args
在符合 Unix 的系统上(-I
在 POSIX 中是可选的,仅适用于符合 UNIX 的系统),您需要预处理输入引用预期格式的行xargs
:
< file sed 's/"/"\\""/g;s/.*/"&"/' |
xargs -E '' -I{} command --option {} other args
但请注意,某些xargs
实现对参数的最大大小有非常低的限制(例如,Solaris 上为 255,这是 Unix 规范允许的最小值)。
答案2
使用while read
循环:
: > another_file ## Truncate file.
while IFS= read -r line; do
command --option "$line" >> another_file
done < file
另一种是按块重定向输出:
while IFS= read -r line; do
command --option "$line"
done < file > another_file
最后是打开文件:
exec 4> another_file
while IFS= read -r line; do
command --option "$line" >&4
echo xyz ## Another optional command that sends output to stdout.
done < file
如果其中一个命令读取输入,最好使用另一个 fd 进行输入,这样命令就不会吃掉它(这里假设ksh
,zsh
或bash
for -u 3
,使用<&3
可移植的方式代替):
while IFS= read -ru 3 line; do
...
done 3< file
最后要接受参数,你可以这样做:
#!/bin/bash
file=$1
another_file=$2
exec 4> "$another_file"
while IFS= read -ru 3 line; do
command --option "$line" >&4
done 3< "$file"
哪一个可以运行为:
bash script.sh file another_file
额外的想法。与bash
, 使用readarray
:
readarray -t lines < "$file"
for line in "${lines[@]}"; do
...
done
注意:IFS=
如果您不介意删除行值的前导空格和尾随空格,则可以省略。
答案3
准确地回答这个问题:
#!/bin/bash
# xargs -n param sets how many lines from the input to send to the command
# Call command once per line
[[ -f $1 ]] && cat $1 | xargs -n1 command --option
# Call command with 2 lines as args, such as an openvpn password file
# [[ -f $1 ]] && cat $1 | xargs -n2 command --option
# Call command with all lines as args
# [[ -f $1 ]] && cat $1 | xargs command --option
答案4
sed "s/'/'\\\\''/g;s/.*/\$* '&'/" <<\FILE |\
sh -s -- command echo --option
all of the{&}se li$n\es 'are safely shell
quoted and handed to command as its last argument
following --option, and, here, before that echo
FILE
输出
--option all of the{&}se li$n\es 'are safely shell
--option quoted and handed to command as its last argument
--option following --option, and, here, before that echo