yae*_*ael 2 bash text-processing
在某些情况下,当我们想在文件中添加新行时,我们会看到我们添加的新行已插入到最后一行的末尾
例如,这里追加之前的文件:
more /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
Run Code Online (Sandbox Code Playgroud)
现在我们附加:
echo "182.2.3.4 host_1" >>/etc/hosts
Run Code Online (Sandbox Code Playgroud)
我们得到:
more /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6182.2.3.4 host_1
Run Code Online (Sandbox Code Playgroud)
也许最简单的解决方案是:
echo >> /etc/hosts
Run Code Online (Sandbox Code Playgroud)
但我很乐意得到一些其他解决方案的想法。
ilk*_*chu 14
这是因为原始文件在最后一行的末尾没有换行符。echo "182.2.3.4 host_1"
不会在开头添加一个(但会在末尾添加一个, after ...host_1
),因此生成的文件没有一个。
由于这样的问题,并且严格来说,因为标准要求“行”以换行符结尾,所以您应该确保始终将其放在那里。一些实用程序可以在没有最后一个换行符的情况下给出意外的行为(例如,wc -l
计算换行符,所以不会将这样的行算作一行;read
如果没有看到换行符,内置函数会返回错误状态)。有些编辑总是添加它,有些则没有。在没有的情况下,请确保在最后一行之后按 Enter 键,或者查看是否可以将光标移动到其下方的“空行”以确保换行符在那里。
像这样的文件可以用例如修复
perl -i -pe '$_ .= "\n" unless /\n$/' file-maybe-without-nl.txt
Run Code Online (Sandbox Code Playgroud)
如果它已经存在,它应该保持尾随的换行符原样。(awk 1 < file.txt > fixed.txt
似乎也有效,但 awk 没有标准的就地编辑功能。sed
有,但我不知道如何使用它。)
当然,您也可以无条件地添加类似echo >> /etc/hosts
, or的换行符echo -e '\n182.2.3.4 host_1' >> /etc/hosts
,但是如果在添加之前文件格式正确,则会在中间添加虚假的空行。
无需读取整行即可检查最终换行符的一种方法是使用tail -n1
或tail -c1
获取最后一行(或行片段)或仅获取最后一个字符。然后
[ "$(tail -c1 "$f")" = "" ] || echo >> "$f"
Run Code Online (Sandbox Code Playgroud)
如果需要,可以使用它来添加它。(这依赖于命令替换吃掉任何换行符,所以如果换行符在那里,它的扩展是空的。)或者使用read
(如果没有看到换行符,它返回一个假状态):
tail -c1 file | read -r tmp || echo >> file
Run Code Online (Sandbox Code Playgroud)
(tail
从博客文章中借用的想法和整个后一个命令:https : //backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/)
请注意,回车符 (CR) 与在类 Unix 系统上用作行终止符的换行符/换行符 (LF) 不同。(CR+LF 在 DOS 和 Windows 上用作行终止符。)
归档时间: |
|
查看次数: |
403 次 |
最近记录: |