我有一个包含名称列表的文件。我需要使用 shell 脚本从外部文件中循环遍历此文件中的所有名称。我怎样才能做到这一点?
示例文件:
脚本/名称.txt
alison
barb
charlie
david
脚本/script.sh
NAMES="" #names from names.txt file
for NAME in $NAMES; do
echo "$NAME"
done
如何在单独的 shell 脚本中将 names.txt 文件分解为数组?
一种方法是:
while read NAME
do
echo "$NAME"
done < names.txt
编辑:
请注意,循环在子外壳中执行,因此任何修改的变量都将是本地的,除非您declare
在循环外部声明它们。
丹尼斯威廉姆森是对的。抱歉,一定是经常使用管道结构而感到困惑。
你会想要使用“读取”命令
while read name
do
echo "$name"
done < names.txt
请注意,“$name”是带引号的——如果不是,它将使用中的字符$IFS
作为分隔符进行拆分。如果您只是回显变量,这可能不会被注意到,但是如果您的文件包含要复制的文件名列表,$IFS
那么如果变量未引用,这些文件名将被分解,这不是您想要的或期待。
如果您想使用 Mike Clark 的方法(加载到变量中而不是使用读取),您可以不使用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
cat names.txt|while read line; do
echo "$line";
done
我知道纯粹主义者会讨厌这种方法,但你可以cat
存档。
NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
echo "$NAME"
done
这可能对您有用:
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