如何使用shell迭代外部文件中的行?

Rya*_*yan 29 bash shell

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

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

示例文件:

脚本/ names.txt中

alison
barb
charlie
david
Run Code Online (Sandbox Code Playgroud)

脚本/ script.sh

NAMES="" #names from names.txt file
for NAME in $NAMES; do
    echo "$NAME"
done
Run Code Online (Sandbox Code Playgroud)

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

smo*_*ing 58

一种方法是:

while read NAME
do
    echo "$NAME"
done < names.txt
Run Code Online (Sandbox Code Playgroud)

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

丹尼斯威廉姆森是对的.对不起,必须经常使用管道构造并感到困惑.

  • 不,因为没有任何东西被输入`while`,所以没有子shell.重定向到`done`不会创建子shell. (2认同)

Bar*_*den 14

你会想要使用'read'命令

while read name
do
    echo "$name"
done < names.txt
Run Code Online (Sandbox Code Playgroud)

请注意,引用了"$ name" - 如果不是,则将使用$IFSas delimiters中的字符进行拆分.如果您只是回显变量,这可能不会被注意到,但是如果您的文件包含要复制的文件名列表,$IFS那么如果变量未加引号,那么这些文件名就会被分解,这不是您想要的或者期待.

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

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

这样做的问题是它将整个文件加载到$NAMES,当你把它读回来时,你可以获得整个文件(如果引用)或文件细分$IFS,如果没有引用.默认情况下,这将为您提供单独的单词,而不是单独的行.因此,如果名称"Mary Jane"出现在一行上,您将获得"Mary"和"Jane"作为两个单独的名称.使用read会解决这个问题...虽然你也可以改变它的值$IFS


Arn*_*anc 7

cat names.txt|while read line; do
    echo "$line";
done
Run Code Online (Sandbox Code Playgroud)

  • `读取线; 做......; 完成<names.txt` (4认同)

Mik*_*ark 5

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

NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
   echo "$NAME"
done
Run Code Online (Sandbox Code Playgroud)

  • 这样做的好处是不调用子shell,但会将`names.txt`中的任何空格视为分隔符. (5认同)
  • "纯粹主义者"也将有助于解释这个问题.有很多问题.请参阅http://mywiki.wooledge.org/DontReadLinesWithFor (2认同)