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

时间:2012-07-05 17:54:41

标签: bash shell

  

可能重复:
  Looping through the content of a file in Bash?

我有一个带有名单的文件。我需要使用shell脚本从外部文件遍历此文件中的所有名称。我怎么能这样做?

示例文件:

脚本/ names.txt中

alison
barb
charlie
david

脚本/ script.sh

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

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

5 个答案:

答案 0 :(得分:57)

一种方法是:

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

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

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

答案 1 :(得分:13)

您将要使用'read'命令

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

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

如果您想使用Mike Clark的方法(加载到变量而不是使用read),您可以在不使用cat的情况下执行此操作:

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

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

的值

答案 2 :(得分:7)

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:2)

这可能对您有用:

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