我想执行以下操作,逐行读取并使用每行的值作为参数
FILE="cat test"
echo "$FILE" | \
while read CMD; do
echo $CMD
done
但是当我执行echo $ CMD时,它只返回cat:S
答案 0 :(得分:103)
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
< "$FILE"
的重定向优于cat "$FILE" | while ...
。它避免了useless use of cat,从而节省了不必要的子进程。它还避免了循环在子shell中运行的常见缺陷。在bash中,|
管道中的命令在子shell中运行,这意味着在循环结束后变量赋值将丢失。使用<
重定向没有问题,因此您可以在循环后使用$CMD
或修改循环内的其他变量。它还可以避免不必要的子进程。
可以进行一些其他改进:
IFS=
,以便read
不会修剪每行的前导和尾随空格。-r
以进行读取,以防止反斜杠被解释为转义序列。CMD
和FILE
。 bash约定只是环境和内部shell变量是大写的。printf
是echo
之类的字符串,$cmd
会将其解释为旗帜,请使用-n
代替echo
更安全。file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
答案 1 :(得分:79)
你所拥有的是将文本"cat test"
传递到循环中。
你只想:
cat test | \
while read CMD; do
echo $CMD
done
答案 2 :(得分:13)
xargs
是将输出拆分为命令参数的最灵活的解决方案。
由于其参数化简单,它也非常易读且易于使用。
格式为xargs -n $NUMLINES mycommand
。
例如,要echo
文件/tmp/tmp.txt
中的每个单独行:
cat /tmp/tmp.txt | xargs -n 1 echo
或diff
每个连续的文件对列在您上面名称的文件中的行中:
cat /tmp/tmp.txt | xargs -n 2 diff
-n 2
指示xargs
使用并作为单独的参数传递两行您一次输入的内容。
你可以定制xargs
除了回车符/换行符之外还要拆分分隔符。
使用man xargs
和谷歌查找有关此多功能实用程序功能的更多信息。
答案 3 :(得分:2)
你的意思是:
cat test | \
while read CMD; do
echo $CMD
done
答案 4 :(得分:2)
如果要将文件的每一行用作应用程序的命令行参数,可以使用xargs命令。
xargs -a <params_file> <command>
一个params文件:
a
b
c
d
和文件tr.py:
import sys
print sys.argv
执行
xargs -a params ./tr.py
给出了结果:
['./tr.py', 'a', 'b', 'c', 'd']
答案 5 :(得分:0)
while read CMD; do
echo $CMD
done << EOF
data line 1
data line 2
..
EOF
答案 6 :(得分:-1)
您的脚本的正确版本如下;
FILE="cat test"
$FILE | \
while read CMD; do
echo $CMD
done
然而,这种间接性 - 在名为FILE--的变量中输入命令是不必要的。使用已提供的解决方案之一。我只想指出你的错误。