为什么行尾$锚不与grep命令一起使用,即使行前^锚也是如此?


19

对UNIX来说是很新的知识,但对编程却不是新知识。在MacBook上使用终端。为了管理和搜索用于填字游戏的单词列表,我尝试使用Grep命令及其变体来方便使用。似乎很简单,但是早就习惯了我认为应该是一个简单的案例。

当我进入

grep "^COW" masternospaces.txt

我得到了我想要的:以COW开头的所有单词的列表。

但是当我进入

grep "COW$" masternospaces.txt

我希望得到以COW结尾的单词列表(有很多这样的单词),并且什么也没有返回。

该文件是纯文本文件,每行在所有大写字母中只有一个单词(或没有空格的单词短语)。

知道这里会发生什么吗?


3
masternospaces.txt文件的来源是什么?是否有Windows样式的线路终端(CR-LF)而不是Unix样式的LF?
steeldriver 2014年

2
不确定,但是您要查找列表单词还是列表...
mikeserv 2014年

钢铁司机-那样的事情是我的第一个想法。不确定如何检查那里发生的事情,甚至可能发生的情况。假定最终收益是最终收益。该文件是来自几个来源的大量汇编。我什至不确定哪一个文件将被视为原始文件。在PC和Mac计算机上,至少要经过三个字处理器。查看它正在使用哪种端接的最佳方法是什么?
DTalvacchio 2014年

mikeserv-在此.txt文件中,每一行只是一个单词(或单词之间没有空格的短语,因此也是一个“单词”)。我想,所以我正在寻找线。。。只是每行只有一个我正在考虑填字游戏的单词。
DTalvacchio 2014年

1
您可以hexdump用来检查行尾的格式。我建议你用我最喜欢的格式:hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt。用输出检查行尾:0a-> LF0d-> CR
user43791 2014年

Answers:


23

正如@steeldriver所提到的,问题很可能是由与grep预期不同的换行符样式引起的。

检查行尾

您可以hexdump用来检查行尾的格式。我建议您使用我最喜欢的格式:

hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt

用输出检查行尾:0a-> LF0d-> CR。一个非常简单的示例将给出以下内容:

$ hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
00000000 (0x00000000)    4e 6f 20 43 4f 57 20 65   6e 64 69 6e 67 0d 0a 45    No COW e|nding..E
00000016 (0x00000010)    6e 64 69 6e 67 20 69 6e   20 43 4f 57 0d 0a          nding in| COW..

注意在DOS格式的行结束:0d 0a

更改行尾

您可以在这里此处看到使用各种工具更改行尾的各种方法,但是对于一次性的事情,您始终可以使用vi / vim:

vim masternospaces.txt
:set fileformat=unix
:wq

不用更改就可以grep

如果您只想grep匹配行尾,则可以始终这样指定行尾:

grep 'COW[[:cntrl:]]*$' masternospaces.txt

如果显示空白行,则可以使用以下-v选项检查是否确实匹配cat

grep 'COW[[:cntrl:]]*$' masternospaces.txt | cat -v

我个人的最爱

您还可以使用sed以下命令grep和标准化输出:

sed -n '/COW^M*$/{;s/^M//g;p;};' masternospaces.txt

其中,^M通过输入获得的Ctrl-V Ctrl-M键盘上。

希望这可以帮助!


这都是非常有帮助的。今天时间不多了,但明天将仔细检查所有这些内容,看看会发生什么。同时,如果您中有任何人有到您最喜欢的Unix命令参考指南的链接,以便我可以对自己进行一些了解,我将不胜感激。我一直在这里和那里捡拾东西,但还没有找到一个来源来作为我的解释。谢谢大家,明天将进行检查并进行成功的更新。--D
DTalvacchio

至少对我来说,这篇帖子没有关闭是很糟糕的。对于我的一生,我无法弄清楚如何匹配行尾。如果我执行十六进制转储,则找不到像上面的示例一样的结尾结尾的行。我对使用十六进制不熟悉,因此可能阅读不正确。我也尝试了[[:cntrl:]]建议的@ user43791,但它仍然与我不匹配。这是没有道理的。我正在使用GNU grep 2.20,并分析了nDPI的输出,该输出已写入文本文件
harperville,2016年

@harperville如果cat -v yourfile.ext您看到了什么?
user43791'3

好吧,没有什么令人兴奋或意外的。只是我希望看到的内容。您要寻找什么具体的东西?我无法在此处粘贴输出,但只能看到其内容。根据的常规ol'“ ASCII英文文本” file
哈珀维尔

@harperville每行末尾是否没有多余的“ ^ M”?您可以粘贴十六进制的前几行吗?
user43791 '16

1

尽管您可以在grep中使用“标准” RegEx语法(如@ user43791的answer所示),但grep还具有其他标识符来表示输入边界。

整行开头和结尾的匹配项是\`(反引号)(而不是^)和\'(撇号)(而不是$)。

因此,对于原始命令,您将使用: grep "COW\'" masternospaces.txt

附注:同样重要的是要注意,?+,除非你逃脱他们使用将被逐字处理\?,并\+让他们自己的正则表达式的风格选择同行。

来源:grep正则表达式语法


grep正在以^(脱字符)作为开始,以\'(撇号)作为结束
GypsyCosmonaut

1

删除\rgrep之前的另一种方法:

... | dos2unix | egrep 'COW$' | ...

我喜欢这一点,因为我[[:cntrl:]]很久都不记得了。


-2

bash为grep设置参数时,“ COW $”被解释为“ COW”,其中将“ $”视为“”,因为$是转义符号。当$没有任何内容时,bash shell会将其解释为空字符串,因此,应改用grep'COW $'masternospaces.txt。


3
由于没有有效的扩展$,它将由bash单独保留并由grep使用。自己看看:echo "COW$"- $遗嘱仍然存在。
杰夫·谢勒

-3

在BSD grep中,您需要转义“ $”并将字符串用双引号引起来:

"COW\$"

1
不。该$不会是特别的外壳,因为其后的东西是不是一个有效的shell变量名。在静态字符串周围使用单引号是一个更好的主意,但是在这里没有什么区别。
库沙兰丹
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.