我有一个简单的脚本,使用curl获取一些纯文本文件,将其分配给变量;稍后它会回复它并为某些行打开它,将它们放入临时文件中(我实际上想把它们放在一个数组中);然后通过他们迭代并做一些事情。 我在Mac OS X上的一台机器上运行它,它主要工作。 但是,随机发生以下任何一种情况:
有没有什么方法可以确保一致地处理换行符?我甚至不关心如何,只要它总是一样的,如果需要,我也可以从单线卷曲输出中获得结果。
更新:来自不同的地方。登录到机器,做了一些东西,注意到脚本不起作用。跑一些命令(结果,删节,下面)测试,注销,重新登录,行为改变(回到预期的一个)。请注意for循环输出之间的区别...对于我的curl输出也是如此,其中完全相同的命令(对于所有我知道)完全相同的env以不同的方式处理换行符。 我想要做的是在每个脚本的开头运行一些命令,使其100%确定行为永远不会改变。
[root@ip-xxx-xxx-xxx-xxx ~]# cat example.txt
ip-xxx-xxx-xxx-xxx.ec2.internal
ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# for f in `cat example.txt`; do echo "line $f"; done
line ip-xxx-xxx-xxx-xxx.ec2.internal
ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# while read f; do echo "line $f"; done < "example.txt"
line ip-xxx-xxx-xxx-xxx.ec2.internal
line ip-xxx-xxx-xxx-xxx.ec2.internal
[root@ip-xxx-xxx-xxx-xxx ~]# logout
Connection to ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com closed.
reznor-mbp:trunk2 sergey$ ssh -i ... "root@..."
Last login: ...
[root@ip-xxx-xxx-xxx-xxx ~]# for f in `cat example.txt`; do echo "line $f"; done
line ip-xxx-xxx-xxx-xxx.ec2.internal
line ip-xxx-xxx-xxx-xxx.ec2.internal
答案 0 :(得分:4)
第一:不要用for读取行;用while read
循环读取它们:
while read -r; do
echo "line $REPLY"
done <example.txt
for f in $(cat example.txt)
的问题是cat操作的输出在进入循环之前经过字符串拆分和glob扩展,使得行为依赖于许多变量(IFS
的内容shell设置,当前目录中的文件[如果存在可能的全局扩展名称],影响如何解释globs的各种shell选项等)。 while read
方法将保持一致。
第二 - 总是引用扩展出于同样的原因:"$line"
避免字符串拆分和全局扩展(再次,使上述设置和变量没有实际意义),而裸$line
则会发生这种情况。 / p>
最后,上面的示例使用默认的REPLY
变量,因为shell在这些条件下不会修剪空白字符(即$IFS
中找到的字符)。这通常是不必要的(通过明确清除IFS可以产生相同的效果,如while IFS= read -r line; do ...
),但由于目标是可重现的,我们正在做正确的事。 :)
遵循这些惯例,您将看到符合POSIX sh的所有shell之间的一致行为。 (唯一不符合POSIX sh的主要shell - 默认情况下,在认为标准强制行为不合理的地方违反兼容性 - 是zsh)。
答案 1 :(得分:0)
你提到echo
。你写的是
echo $multiLineVar
或
echo "$multiLineVar"
在第一种情况下,shell会将嵌入的换行视为分隔单词的空格,因此echo
永远不会看到它们。
答案 2 :(得分:0)
简单的方法是使用while循环,如下所示
filename=/path/to/file/file.txt
while read variablename
do
echo "$variablename"
done < "filename"
它的作用是读取整行直到\ n