如何使用 shell 遍历外部文件中的行? [复制]
Posted
技术标签:
【中文标题】如何使用 shell 遍历外部文件中的行? [复制]【英文标题】:How do I iterate through lines in an external file with shell? [duplicate] 【发布时间】:2012-07-06 04:22:06 【问题描述】:我有一个包含名称列表的文件。我需要使用 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 文件分解为数组?
【问题讨论】:
原始问答的链接怎么样? 【参考方案1】:一种方法是:
while read NAME
do
echo "$NAME"
done < names.txt
编辑:
请注意,循环在子 shell 中执行,因此任何修改的变量都将是本地的,除非您在循环外使用 declare
声明它们。
丹尼斯威廉姆森是对的。抱歉,一定是因为太频繁地使用管道结构而弄糊涂了。
【讨论】:
不,因为没有任何东西被传送到while
,所以没有子shell。重定向到done
不会创建子shell。
顺便说一下,管道问题(错误?)不会出现在 korn shell 中(但会出现在 pdksh 中)。
有人应该澄清你正在循环的文件的最后一行应该是空的,否则最后一个元素将不会被考虑【参考方案2】:
您会想要使用“读取”命令
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
的值
【讨论】:
【参考方案3】:cat names.txt|while read line; do
echo "$line";
done
【讨论】:
while read line; do ...; done < names.txt
【参考方案4】:
我知道纯粹主义者会讨厌这种方法,但您可以cat
文件。
NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
echo "$NAME"
done
【讨论】:
这具有不调用子shell的优点,但会将names.txt
中的任何空格视为分隔符。
“纯粹主义者”也将有助于解释这有什么问题。有多个问题。见mywiki.wooledge.org/DontReadLinesWithFor【参考方案5】:
这可能对你有用:
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
【讨论】:
以上是关于如何使用 shell 遍历外部文件中的行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章