Answers:
使用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
为-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=
如果您不介意将行值修剪为前导空格和尾随空格,可以将其省略。
另一个选择是xargs
。
使用GNU xargs
:
< file xargs -I{} -d'\n' command --option {} other args
{}
是文本行的占位符。
其他的xargs
则没有-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规范允许的最小值)。
精确地回答这个问题:
#!/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
我发现的最佳答案是:
for i in `cat`; do "$cmd" "$i"; done < $file
编辑:
...四年后...
经过几次否决和更多的经验后,我现在建议以下
xargs -l COMMAND < file
do "$cmd" "$i";
除非有理由不这么做,否则应始终引用对shell变量的引用(如中所述)。如果文件*
本身包含一个单词,那么您的代码将运行$cmd *
,该代码当然将运行命令并显示当前目录中的文件列表。
zsh
,`cat`
将已经扩展了*
(如果引号$i
的扩展`cat`
引入了通配符,则第二引号仍可以扩展未引号)。无论如何,这种方法确实是错误的。
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
ed file.txt
%g/^/s// /
2,$g/^/-,.j
1s/^/command/
wq
chmod 755 file.txt
./file.txt
将文件的所有行作为参数传递给单个命令,即
command line1 line2 line3 ....
如果您需要--option
在每行之前放置标志,请将第二个命令更改为:
%g/^/s// --option /
'
,"
,<
,>
,;
,等。(3)这产生了不必要的临时文件。(4)此类事情通常是通过“此处文档”完成的。(5)您的ed
命令很笨拙;前两个命令可以简化为%s/^/ /
和%j
。
<file xargs -L 1 -I{} command --option {} other args