关于bash:如何使用shell迭代外部文件中的行?

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

本问题已经有最佳答案,请猛点这里访问。

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

我有一个文件,上面有名字列表。我需要用shell脚本从一个外部文件遍历这个文件中的所有名称。我该怎么做?

示例文件:

脚本/名称.txt

1
2
3
4
alison
barb
charlie
david

脚本/script.sh

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

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


一种方法是:

1
2
3
4
while read name
do
    echo"$name"
done < names.txt

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

丹尼斯·威廉姆森是对的。抱歉,一定是使用管道结构太频繁了,而且弄糊涂了。


您将希望使用"read"命令

1
2
3
4
while read name
do
    echo"$name"
done < names.txt

注意,$name被引用——如果没有,它将使用$IFS中的字符作为分隔符进行拆分。如果您只是在回送变量,这可能不会被注意到,但是如果您的文件包含一个要复制的文件名列表,那么如果变量未被引用(这不是您想要或期望的),那么这些文件名将被$IFS分解。

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

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

问题在于,它将整个文件加载到$NAMES中,当您读回它时,如果不引用,您可以获取整个文件(如果引用)或由$IFS分解的文件。默认情况下,这将为您提供单个单词,而不是单个行。所以如果"玛丽·简"这个名字出现在一行上,你会得到"玛丽"和"简"两个独立的名字。使用read可以解决这个问题…尽管您也可以更改EDOCX1的值(1)


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


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

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


这可能对您有用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat <<\! >names.txt
> alison
> barb
> charlie
> david
> !
OIFS=$IFS; IFS=$'
'
; 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