2

我有一个简单的脚本,它使用 curl 获取一些纯文本文件,并将其分配给变量;稍后它会回显它并将其 grep 用于某些行,将它们放入一个临时文件中(我实际上想将它们放入一个数组中);然后遍历它们并做一些事情。我在 Mac OS X 上的一台机器上运行它,它大部分都可以工作。但是,随机会发生以下任一情况:

  • curl 输出被视为单行,因此在 echo/grep 阶段,事情会中断;
  • 整个 tmp 文件在执行 echo 和 for 循环时被视为单行(我似乎已经使用“读取行”缓解了这种情况),所以它再次中断。

有没有办法确保换行符得到一致的处理,一劳永逸?我什至不在乎只要它始终相同,如果需要,我也可以从单行 curl 输出中提取结果。

更新:来自不同的地方。登录机器,做了一些事情,发现脚本不起作用。运行一些命令(结果,删节,下面)进行测试,注销,重新登录,行为改变(回到预期的)。注意 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
4

3 回答 3

4

第一:不要用 for 读行;while read循环读取它们:

while read -r; do
  echo "line $REPLY"
done <example.txt

问题for f in $(cat example.txt)在于 cat 操作的输出在进入循环之前经过字符串拆分和 glob 扩展,使得行为依赖于许多变量(IFSshell 设置的内容、当前目录中的文件 [如果可能是 glob-存在扩展名称],影响 glob 解释方式的各种 shell 选项等)。该while read方法将表现一致。

其次——出于同样的原因总是引用扩展:"$line"避免字符串拆分和全局扩展(再次,使上述设置和变量没有实际意义),而bare$line却发生了这些。

最后,上面的示例使用默认REPLY变量,因为 shell 在这些条件下读取时不会修剪空白字符(即,在 中找到的字符$IFS)。这通常是不必要的(通过显式清除 IFS 可以获得相同的效果,如 中while IFS= read -r line; do ...所示),但由于目标是可重现的,因此我们做对了。:)

遵循这些做法,您将看到所有符合 POSIX sh 的 shell 之间的行为一致。(唯一不符合 POSIX sh 的主要 shell——在它认为标准强制行为不合理的地方默认破坏兼容性——是 zsh)。

于 2013-04-02T01:44:14.887 回答
0

简单的方法是使用如下的while循环

filename=/path/to/file/file.txt
while read variablename

do echo "$variablename" done < "filename" 它的作用是读取整行直到 \n

于 2014-06-26T12:45:59.010 回答
0

你提echo。你写吗

echo $multiLineVar

或者

echo "$multiLineVar"

在第一种情况下,shell 会将嵌入的换行符视为分隔单词的空格,因此echo永远不会看到它们。

于 2013-03-21T18:38:45.823 回答