使用grep检测行尾的模式


64

如果我做:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

如果我只想列出.rar文件,并且使用grep,它也会向我显示.rar.part文件,这不是我的愿望。
我正在使用findls **/*.rar按照该线程中的说明解决此问题,它们工作正常,但我想了解是否可以通过进行操作grep

我已经尝试过(正在考虑EOL):

ls -R | grep ".rar\n"

没有结果。
我认为问题在于发现是否在该行的末尾找到了greping ,但是我不确定。

请在这里帮忙吗?


为什么要grep在这种情况下使用?为什么不find呢?
devnull 2014年

1
@devnull,了解如何检测仅位于行尾的模式可能在许多情况下很有用。例如:可移植性,在嵌入式Linux中过于简单的路由器中的使用,与UnxUtils for Windows的使用(其find命令与Windows冲突)和...学习;-)。问题不是关于“列出目录中的文件”(这只是一个自定义示例),而是关于“了解grep命令的用法”
Sopalajo de Arrierez 2014年

1
老实说,如果您希望将行尾作为分隔符,则应该使用ls -1R
mikeserv

1
而且您甚至不需要grep。看我的答案。
mikeserv

@mikeserv,不进行-1R切换会发生什么。显然结果是相同的。
Sopalajo de Arrierez 2014年

Answers:


88

所述$锚的线的端部相匹配。

ls -R | grep '\.rar$'

您也可以使用find以下方法:

find . -name '*.rar'

我没有意识到“。” 需要在grep中转义。它被当作通配符吗?
thebunnyrules

1
@thebunnyrules“。在正则表达式中表示任何字符之一。
jordanm

10

除了您的问题外,请注意,.rar它不仅匹配“ .rar”,而且匹配。.之前的每个单个字符(包括)rar。在这种情况下,可能不是问题,但.必须在正则表达式中转义。

ls -R | grep "\.rar$"

您是说.asc*asc图案吗?因此它将匹配,例如whereverasc
Sopalajo de Arrierez 2014年

2
@SopalajodeArrierez不,它不匹配每个字符组,但匹配每个字符,例如xrar
Hauke Laging

5

您还可以指示grep从单词边界开始查找字符串。A .是这些边界之一。

$ ls -R | grep '\brar$'

说我有这个样本数据。

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

此命令将仅找到带有.rar扩展名的文件。

$ ls -R | grep '\brar$'
afile.rar

如何运作?

元字符\b是锚号,例如插入号和美元符号。它在称为“单词边界”的位置匹配。此匹配为零长度。

这种情况不起作用的情况

如果您有命名的文件,blah-rar这些文件也会被检测到。

$ ls -R | grep '\brar$'
afile-rar
afile.rar

这是因为字母数字以外的其他字符通常被认为是边界字符,因此会跳过这种方法。


乍一看似乎是一样的,但确实有些不同。谢谢,@ slm。如果我使用双引号"而不是简单的引号会困扰吗?
Sopalajo de Arrierez 2014年

1
@SopalajodeArrierez-两种方法都不起作用。这将找到任何可能以w /开头的文件.rar。但是使用不会有问题ls -R。仅当您碰巧使用时ls -Ra
slm

你们中的一个人有兴趣向公众解释这种细微差别吗?
Hauke Laging

@HaukeLaging 在我的示例中-P切换到grep。这触发了PCRE对参数的解释。
slm

1
@SopalajodeArrierez-如果文件包含换行符(\n)是合法字符。ls -1R无论如何,都会强制将文件显示在单个列中。
slm

0

做就是了 :

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

您根本不需要grep

注意:上面的作品...除了至少 仍然可以afile-rar我不明白为什么。我会把它留在这里,但我并不为此感到骄傲。无论如何,正如其他人所说:

find . '*.rar'

这不会阻止名为xrar或的文件afile-rar
slm

我仍然在输出中得到其他文件。
slm

@slm还有什么其他文件?我认为这可能是因为它们太短了。我只是注意到自己。我也解决了。
mikeserv 2014年

文件afile-rarxrar仍包含在输出中。您的最新模组也没有变化。讨厌的问题不?尝试不使用常规方法就可以解决问题,这很有趣8
slm

@slm是的,这就是为什么我来这里。我不明白为什么-dash会成功。xrar我可以处理的事情,但-dash.我不了解-dash.
mikeserv

0

使用单引号使$作为行尾使用。如果还要使用某些变量进行grep,请使用双引号和单引号的组合,如下所示:

grep "$var"'$'

我以前的帖子被删除,说它是重复的。让我解释一下这有何不同。

其他文章提到要么完全使用双引号"",要么完全使用单引号''。他们都有自己的局限性。以下说明。

所有双引号的问题如下: grep "pattern$"给出以下错误:Illegal variable name.

并使用所有单引号的工作,但如果你想变量替换,所有的单引号将无法正常工作。例如:

如果我有string A_BOOK,包括文件FILE中的其他字符串。

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

如果我将BOOK设置为变量BK

set BK = BOOK

如果我用所有双引号grep,则会出现以下错误::grep "${BK}$" FILE*1st $用于变量替换,2nd用于模式结尾(非法变量名)。

如果我用所有单引号引起来,则不会发生变量替换。 grep '${BK}$' FILE什么都不返回

如果我使用双引号和单引号的组合,我会得到期望的结果。双引号表示变量替换,单引号表示模式结尾。

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK

看起来您正在使用csh。该"foo$"语法在sh和family上正常工作。
Olorin

是的,奥洛林。我正在使用tcsh。感谢您指出这一点。
user274900

0

如果在执行上述操作后仍然无济于事,则可能是由于行尾。要解决此问题,请执行以下操作:dos2unix pr0n.txt然后grep再执行一次。

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.