我在看似简单的脚本时遇到了问题。
基本上看起来像这样:
for s in $(cat FILENAME| grep User)
do
echo "$s"
done
但是没有给我类似结果:
User bla bla bla
User2 something blabla
结果就是:
User
bla
bla
bla
User2
答案 0 :(得分:0)
cat
和grep
产生的行恰巧包含空格。 for
构造是从每一段而不是每一行中赚取美元。
根据显示的内容,您可以简单地使用cat
和grep
,而不必担心循环。
答案 1 :(得分:0)
就像@donjuedo statet一样,通常将空格视为分隔符,这就是为什么您看不到整行的原因。有几种方法可以解决此问题。 我列出了从文件读取和从命令输出读取的解决方案。作为输入,您可以创建一个具有以下内容的文件,并将其命名为testfile.txt(带有空行,行之间以及两端都有空格的行:
This is the first line
2
third line
fifth line
sixth line
解决方案1:最普遍适用
while IFS= read -u 3 -r line; do
echo ">${line}<"
read -p "press enter to show next line" var
echo "read caught the following input: >$var<"
done 3< testfile.txt
从管道读取的变量看起来完全一样,只是最后一行发生了变化。作为示例,我处理了测试文件中所有包含空格的行,从而消除了第二行和第四行(这里用<&3代替-u 3-两者都是等效的):
while IFS= read -r line <&3; do
...
done 3< <(grep " " testfile.txt)
这适用于大型输入文件。 3 <间接似乎很尴尬,但是请确保循环内的进程仍可以从标准输入中读取(请参阅读取语句“ press enter ...”)。如果执行的命令可能会显示用户提示自己(例如rm等),这可能很重要。 所以:
也适用于大型输入文件,而不会消耗内存
stdin不会重定向(而是使用fd 3)
空间,
空行保留得很好
感谢@BenjaminW提出这个建议。
解决方案2:使用IFS和for(有限制)
OFS="$IFS"
IFS=$'\n'
for line in $(cat testfile.txt) ; do
echo ">${line}<"
read -p "press enter to show next line" var
echo "read caught the following input: >$var<"
done
IFS="$OFS"
这会暂时将字段分隔符更改为换行符,因此仅在换行符处拆分文件。
不建议用于大型输入,因为命令行替换($(cat testfile))
stdin也未重定向,因此可以在体内使用stdin而无需限制
空间,
作为第四行的空行在这里被跳过(行长0 /匹配^ $)
如果使用此功能,则必须确保重置IFS
如果您的循环主体需要对字段进行不同的解释(例如,需要读取其他应在空格周围分割的内容),则可能会变得混乱。