我有这行代码逐行读取文本文件。
文本文件有时由 Windows 用户生成,有时由 Unix 用户生成。因此,有时我看到\r\n
行尾,有时我只看到\n
.
我希望我的脚本能够处理这两种情况并分别到达每一行,而不管换行符是\r
, or \n
, or \r\n
, or \n\r
。
while read -r textFileLines; do ... something ...; done < text_file.txt
此代码在\n\r
每行末尾与(LF CR) 一起使用,但当我在行尾使用时不起作用!\r\n
测试
使用创建一个新的文本文件
Notepad++ v7.5.4
while read -r LINE; do echo "$LINE"; done < /cygdrive/d/test_text.txt
终端中的输出:
first_line second_line third_string
为什么没有fourth_output
显示线?
在您的图像中,该文件在最后一行末尾缺少换行符。
read
仅当它读取分隔符(换行符)时才返回 true,并且由于最后一行的末尾不存在,因此read
返回 false,循环结束,并且最后一个不完整的行不打印。这与回车无关,即使只有 NL,如果最后一行缺少 NL,行为也是一样的。
在这里,
file1
有两行以 CRLF 行结尾:file2
缺少以第二行结尾的行:如果你想让循环也处理最后一行片段,你必须检查
read
变量read
本身返回失败时是否包含任何数据:如果您想摆脱 CR,您可以在循环中将其删除,例如
x=${x%$'\r'};
(在 Bash/ksh/zsh 中),或使用 or 等预处理tr -d '\r'
文件dos2unix
。有明确的工具可以做到这一点。可用于
\r\n
从文件中剥离的更常见的一种称为dos2unix
.如果这在您的系统上不可用,您可以使用以下命令之一对您的
awk sed 1 sed 2 trtextFileLines
变量执行类似的操作:当然还有很多其他的方法可以做到这一点,这些只是一些比较常见的方法。
参考
如果您有一些文件是 DOS 文本文件,而一些文件是 Unix 文本文件,则您的脚本可以通过以下方式传递所有数据
dos2unix
:Unix 文本文件不会因此而被修改。
为了另外应对Mac换行符,我相信你应该能够做到
最后一行没有被
read
循环输出,因为它没有终止,因此根本不是一行。要检测文件是否在最后一行没有终止换行符,如果没有,则添加一个,在
bash
:有关的:
执行:
所有问题都解决了。
描述:
要更正缺少的最后一个换行符,请使用:
只有在需要时才会添加尾随换行符(不会更改正确的文件)。
然后,您可以转换
\r\n
(DOS 风格)到\n
(只需删除行尾的 \r)\n\r
(无效的 DOS 样式?)到一\n
(在行首删除 \r)\r
(旧MAC)转换为\n
在 (GNU) sed 的一次调用中:
如果文本文件是这样的测试文件: