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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:06:39  来源:igfitidea点击:

Read line by line in bash script

linuxbash

提问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 $CMDafter 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 that readwon't trim leading and trailing whitespace from each line.
  • Add -rto read to prevent from backslashes from being interpreted as escape sequences.
  • Lower case CMDand FILE. The bash convention is only environmental and internal shell variables are uppercase.
  • Use printfin place of echowhich is safer if $cmdis a string like -n, which echowould interpret as a flag.
  • 添加IFS=以便read不会修剪每行的前导和尾随空格。
  • 添加-r到 read 以防止反斜杠被解释为转义序列。
  • 小写CMDFILE。bash 约定只是环境和内部 shell 变量是大写的。
  • 如果是类似 的字符串,则使用它printf来代替echo更安全,这将解释为标志。$cmd-necho
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

xargsis 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 echoeach individual line in a file /tmp/tmp.txtyou'd do:

例如,对于echo文件中的每一行,/tmp/tmp.txt您将执行以下操作:

cat /tmp/tmp.txt | xargs -n 1 echo

Or to diffeach 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 2instructs xargsto consume and pass as separate arguments two lines of what you've piped into it at a time.

-n 2指令xargs一次将您输入的两行内容作为单独的参数使用和传递。

You can tailor xargsto split on delimiters besides carriage return/newline.

xargs除了回车/换行符之外,您还可以根据分隔符进行拆分。

Use man xargsand 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