繁体   English   中英

如何确保bash中的换行符一致

[英]How to ensure consistent newline treatment in bash

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

  • curl输出被视为单行,因此在echo / grep阶段,东西中断了;
  • 整个tmp文件在执行回显和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

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

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

for f in $(cat example.txt)的问题在于,cat操作的输出在进入循环之前经过字符串拆分和glob扩展,从而使行为取决于许多变量( IFS Shell设置的内容) ,当前目录中的文件(如果存在可能的glob扩展名),影响shell解释方式的各种shell选项等)。 while read方式将始终如一。

其次-总是出于相同的原因引用扩展名: "$line"避免字符串拆分和glob扩展(再次使上述设置和变量无意义),而裸$line会出现这种情况。

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

遵循这些实践,您将看到所有兼容POSIX sh的外壳之间的行为一致。 (唯一不符合POSIX sh的主要shell(默认情况下会在认为标准行为不合理的地方破坏兼容性)是zsh)。

你提到echo 你写吗

echo $multiLineVar

要么

echo "$multiLineVar"

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

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

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

do echo "$variablename" done < "filename"它所做的是读取整行,直到\\ n

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM