我有一个带有名单的文件。我需要使用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文件分解为数组?
答案 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