在bash脚本中逐行阅读

时间:2011-01-09 22:15:06

标签: linux bash

我想执行以下操作,逐行读取并使用每行的值作为参数

FILE="cat test"
echo "$FILE" | \
while read CMD; do
echo $CMD
done

但是当我执行echo $ CMD时,它只返回cat:S

7 个答案:

答案 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以进行读取,以防止反斜杠被解释为转义序列。
  • 小写CMDFILE。 bash约定只是环境和内部shell变量是大写的。
  • 如果printfecho之类的字符串,$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--的变量中输入命令是不必要的。使用已提供的解决方案之一。我只想指出你的错误。