bash 如何使用 shell 遍历外部文件中的行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11349827/
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-09-09 22:22:47  来源:igfitidea点击:

How do I iterate through lines in an external file with shell?

bashshell

提问by Ryan

Possible Duplicate:
Looping through the content of a file in Bash?

可能的重复:
在 Bash 中循环遍历文件的内容?

I have one file with a list of names. I need to loop through all names in this file from an external file with a shell script. How can I do that?

我有一个包含名称列表的文件。我需要从带有 shell 脚本的外部文件中遍历此文件中的所有名称。我怎样才能做到这一点?

Example files:

示例文件:

scripts/names.txt

脚本/名称.txt

alison
barb
charlie
david

scripts/script.sh

脚本/脚本.sh

NAMES="" #names from names.txt file
for NAME in $NAMES; do
    echo "$NAME"
done

How can I explode the names.txt file into an array in a separate shell script?

如何在单独的 shell 脚本中将 names.txt 文件分解为数组?

回答by smocking

One way would be:

一种方法是:

while read NAME
do
    echo "$NAME"
done < names.txt

EDIT:Note that the loop gets executed in a sub-shell, so any modified variables will be local, except if you declare them with declareoutside the loop.

编辑:请注意,循环在子 shell 中执行,因此任何修改的变量都将是本地的,除非您declare在循环外声明它们。

Dennis Williamson is right. Sorry, must have used piped constructs too often and got confused.

丹尼斯威廉姆森是对的。抱歉,一定是过于频繁地使用管道结构而感到困惑。

回答by Barton Chittenden

You'll be wanting to use the 'read' command

你会想要使用“读取”命令

while read name
do
    echo "$name"
done < names.txt

Note that "$name" is quoted -- if it's not, it will be split using the characters in $IFSas delimiters. This probably won't be noticed if you're just echoing the variable, but if your file contains a list of file names which you want to copy, those will get broken down by $IFSif the variable is unquoted, which is not what you want or expect.

请注意,“$name”被引用——如果不是,它将使用中的字符$IFS作为分隔符进行拆分。如果您只是回显变量,这可能不会被注意到,但是如果您的文件包含要复制的文件名列表,$IFS那么如果变量未加引号,这些将被分解,这不是您想要的或期待。

If you want to use Mike Clark's approach (loading into a variable rather than using read), you can do it without the use of cat:

如果您想使用 Mike Clark 的方法(加载到变量中而不是使用 read),您可以不使用cat

NAMES="$(< scripts/names.txt)" #names from names.txt file
for NAME in $NAMES; do
    echo "$NAME"
done

The problem with this is that it loads the whole file into $NAMES, when you read it back out, you can either get the whole file (if quoted) or the file broken down by $IFS, if not quoted. By default, this will give you individual words, not individual lines. So if the name "Mary Jane" appeared on a line, you would get "Mary" and "Jane" as two separate names. Using readwill get around this... although you could also change the value of $IFS

这里的问题是,它加载整个文件到$NAMES,当你读它背出来,你可以得到整个文件(如果引用)或文件被打破$IFS,如果没有报价。默认情况下,这将为您提供单独的单词,而不是单独的行。因此,如果名称“Mary Jane”出现在一行中,您将得到“Mary”和“Jane”作为两个独立的名称。使用read将解决这个问题......虽然你也可以改变$IFS

回答by Arnaud Le Blanc

cat names.txt|while read line; do
    echo "$line";
done

回答by Mike Clark

I know the purists will hate this method, but you can catthe file.

我知道纯粹主义者会讨厌这种方法,但是您可以使用cat该文件。

NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
   echo "$NAME"
done

回答by potong

This might work for you:

这可能对你有用:

cat <<\! >names.txt
> alison
> barb
> charlie
> david
> !
OIFS=$IFS; IFS=$'\n'; NAMES=($(<names.txt)); IFS=$OIFS
echo "${NAMES[@]}"
alison barb charlie david
echo "${NAMES[0]}"
alison
for NAME in "${NAMES[@]}";do echo $NAME;done
alison
barb
charlie
david