Linux 在 bash 脚本中逐行读取
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4642191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read line by line in bash script
提问by user385948
I want to do the following, read line by line of a file and use the value per line as params
我想执行以下操作,逐行读取文件并将每行的值用作参数
FILE="cat test"
echo "$FILE" | \
while read CMD; do
echo $CMD
done
but when I do the echo $CMD, it just returns cat :S
但是当我执行 echo $CMD 时,它只返回 cat :S
采纳答案by Oliver Charlesworth
What you have is piping the text "cat test"
into the loop.
您所拥有的是将文本管道化"cat test"
到循环中。
You just want:
你只想要:
cat test | \
while read CMD; do
echo $CMD
done
回答by John Kugelman
FILE=test
while read CMD; do
echo "$CMD"
done < "$FILE"
A redirection with < "$FILE"
has a few advantages over cat "$FILE" | while ...
. It avoids a useless use of cat, saving an unnecessary child process. It also avoids a common pitfall where the loop runs in a subshell. In bash, commands in a |
pipeline run in subshells, which means variable assignments are lost after the loop ends. Redirection with <
doesn't have that problem, so you could use $CMD
after the loop or modify other variables inside the loop. It also, again, avoids unnecessary child processes.
与重定向< "$FILE"
超过了一些优势cat "$FILE" | while ...
。它避免了cat的无用使用,从而节省了不必要的子进程。它还避免了循环在子外壳中运行的常见陷阱。在 bash 中,|
管道中的命令在子 shell 中运行,这意味着循环结束后变量分配将丢失。重定向<
没有这个问题,所以你可以$CMD
在循环之后使用或修改循环内的其他变量。同样,它还避免了不必要的子进程。
There are some additional improvements that could be made:
还可以进行一些额外的改进:
- Add
IFS=
so thatread
won't trim leading and trailing whitespace from each line. - Add
-r
to read to prevent from backslashes from being interpreted as escape sequences. - Lower case
CMD
andFILE
. The bash convention is only environmental and internal shell variables are uppercase. - Use
printf
in place ofecho
which is safer if$cmd
is a string like-n
, whichecho
would interpret as a flag.
- 添加
IFS=
以便read
不会修剪每行的前导和尾随空格。 - 添加
-r
到 read 以防止反斜杠被解释为转义序列。 - 小写
CMD
和FILE
。bash 约定只是环境和内部 shell 变量是大写的。 - 如果是类似 的字符串,则使用它
printf
来代替echo
更安全,这将解释为标志。$cmd
-n
echo
file=test
while IFS= read -r cmd; do
printf '%s\n' "$cmd"
done < "$file"
回答by Joel
Do you mean to do:
你的意思是:
cat test | \
while read CMD; do
echo $CMD
done
回答by Santiago Alessandri
If you want to use each of the lines of the file as command-line params for your application you can use the xargs command.
如果您想将文件的每一行用作应用程序的命令行参数,您可以使用 xargs 命令。
xargs -a <params_file> <command>
A params file with:
一个 params 文件:
a
b
c
d
and the file tr.py:
和文件 tr.py:
import sys
print sys.argv
The execution of
的执行
xargs -a params ./tr.py
gives the result:
给出结果:
['./tr.py', 'a', 'b', 'c', 'd']
回答by Umut Utkan
The correct version of your script is as follows;
您的脚本的正确版本如下;
FILE="cat test"
$FILE | \
while read CMD; do
echo $CMD
done
However this kind of indirection --putting your command in a variable named FILE-- is unnecessary. Use one of the solutions already provided. I just wanted to point out your mistake.
然而,这种间接——将你的命令放在一个名为 FILE 的变量中——是不必要的。使用已经提供的解决方案之一。我只是想指出你的错误。
回答by KomodoDave
xargs
is the most flexible solution for splitting output into command arguments.
xargs
是将输出拆分为命令参数的最灵活的解决方案。
It is also very human readable and easy to use due to its simple parameterisation.
由于其简单的参数化,它也非常易读且易于使用。
Format is xargs -n $NUMLINES mycommand
.
格式为xargs -n $NUMLINES mycommand
.
For example, to echo
each individual line in a file /tmp/tmp.txt
you'd do:
例如,对于echo
文件中的每一行,/tmp/tmp.txt
您将执行以下操作:
cat /tmp/tmp.txt | xargs -n 1 echo
Or to diff
each successive pair of files listed as lines in a file of the above name you'd do:
或者对于diff
在上述名称的文件中作为行列出的每一对连续文件,您可以执行以下操作:
cat /tmp/tmp.txt | xargs -n 2 diff
The -n 2
instructs xargs
to consume and pass as separate arguments two lines of what you've piped into it at a time.
该-n 2
指令xargs
一次将您输入的两行内容作为单独的参数使用和传递。
You can tailor xargs
to split on delimiters besides carriage return/newline.
xargs
除了回车/换行符之外,您还可以根据分隔符进行拆分。
Use man xargs
and google to find out more about the power of this versatile utility.
使用man xargs
和 google 来了解有关此多功能实用程序功能的更多信息。
回答by Mark Yuan
while read CMD; do
echo $CMD
done << EOF
data line 1
data line 2
..
EOF