如何让 grep 忽略 windows 换行符?

How to make grep ignore windows line breaks?

On Mac OS X 我有一个包含 windows 换行符和以下内容的文件

$ file file_windows.txt 
file_windows.txt: ASCII text, with CRLF line terminators
$ cat file_windows.txt
IgnoreMe
FindMe

奇怪的是,当我使用 grep 匹配 "FindMe" 并将结果与​​另一个变量组合时,grep 的结果被忽略了:

$ echo $(grep "FindMe" file_windows.txt)$SHELL
/bin/bash

当我将文件转换为使用 unix 行结尾时

tr -d '\r' < file_windows.txt > file_unix.txt 

突然我的 grep 命令与另一个变量结合使用了

$ echo $(grep "FindMe" file_unix.txt)$SHELL
FindMe/bin/bash

如何让 grep 忽略 (windows) 换行符,以便将 grep 的结果与另一个变量组合在一起的以下命令始终按预期工作?

试试这个:

tr -d $'\r' < file_windows.txt > file_unix.txt 

sed -e 's/\r$//' file_windows.txt > file_unix.txt 

或者由于您使用的是 OsX,您可以安装 dos2unix

此致

克劳迪奥

当你运行:

$ echo $(grep "FindMe" file_windows.txt)$SHELL

echo 将打印包含 FindMe 的行,而 FindMe 又包含一个 \r 字符,因此 $SHELL 将 覆盖 FindMe\r。您可以通过将 echo 重定向到文件来轻松检查这一点。

要解决此问题,您可以要求 grep 以 "zero byte" 终止匹配的字符串,这样:

$ echo $(grep -Z "FindMe" file_windows.txt)$SHELL 

编辑

我确实注意到您正在使用 OSX。在这种情况下使用以下内容:

$ echo $(grep -o "FindMe" file_windows.txt)$SHELL

仅打印 "matching string"

使用

echo "$(tr -d '\r' < file_windows.txt | grep FindMe)$SHELL"

我首先在回显参数周围加上双引号。看起来好多了。
对于无法通过从命令读取来代替从文件读取的其他命令,您可以使用另一个命令

echo "$(grep "FindMe" <(tr -d '\r' < file_windows.txt))$SHELL"

这里发生了什么? 我首先在 echo 参数周围加上双引号。看起来好多了。
您已经找到从标准输入读取的 tr 命令:

tr -d '\r' < file_windows.txt

通过进程替换,您可以使某些进程的输出看起来像另一个进程的文件。 您可以使用

告诉 grep 从 "file" tr -d '\r' < file_windows.txt 中读取
grep "FindMe" <(tr -d '\r' < file_windows.txt)

把它们放在一起就是命令。

echo "$(grep "FindMe" <(tr -d '\r' < file_windows.txt))$SHELL"