如何使用grep查找文件扩展名

36

我目前正在尝试编写一个脚本来使用grep命令查找特定文件类型(例如zip),尽管文件类型之前的文本可以是任何内容,例如:

something.zip
this.zip
that.zip

这些都可以归为同一类别。我正在试图使用通配符来搜索它们,到目前为止我尝试了以下方法:

这些都可以归为同一类别。我正在尝试使用通配符进行搜索,到目前为止我尝试了以下内容

grep ".*.zip"

但每当我这样做时,它可以很好地找到.zip文件,但是如果在.zip后面有其他字符,它仍然会显示输出,例如.zippppppp.zipdsjdskjc仍然会被grep捕获。话虽如此,我应该怎么做才能防止grep显示带有.zip之后附加字符的匹配项?


我发现使用 ripgrep 更好。 - cregox
@cregox,你可能在一个不允许你安装 rip grep 的系统上。 - Daniel L. VanDenBosch
@daniel 是的。还有许多其他可能的错误情况。不过我仍然认为这样做更好。 - cregox
为什么这里发布的任何答案都不能与jar命令一起使用?我正在尝试使用以下命令在JAR文件中grep一些文件:jar tf name-of-my-file.jar | 再加上这里给出的任何一个grep答案,但它返回了空值,而实际上不应该... 有任何想法吗? - Metafaniel
11个回答

86

通过在 $ 后面添加反斜线来转义第二个 . ,以便只匹配句点而不是任何字符。

grep ".*\.zip$"

如果你想要列出当前目录中所有的 .zip 文件,那么使用 ls *.zip 是一个更自然的方式;对于包括当前目录在内的子目录中所有的 .zip 文件,可以使用 find . -name "*.zip"


3
grep "\.zip" 怎么样? - Steve
1
@Steve,\.zip$使用$来表示行尾。这意味着即使文件名中包含“.zip”(这很疯狂),也不会触发过滤器。文件必须具有.zip扩展名才能被过滤器捕获。 - Shrout1
2
grep 命令中第一个点的目的是什么? - FlexMcMurphy

19

在UNIX系统上,请尝试:

find . -type f -name \*.zip

8
您可以使用grep查找具有特定扩展名的所有文件:
find .|grep -e "\.gz$"

.代表当前文件夹。 如果你想指定一个不同于当前文件夹的文件夹,只需用文件夹路径替换.即可。 这里有一个例子:让我们查找所有以.gz结尾且在文件夹/var/log中的文件。

  find /var/log/ |grep -e "\.gz$"

输出结果如下所示:
 ✘ ⚙> find /var/log/ |grep -e "\.gz$"

/var/log//mail.log.1.gz
/var/log//mail.log.0.gz
/var/log//system.log.3.gz
/var/log//system.log.7.gz
/var/log//system.log.6.gz
/var/log//system.log.2.gz
/var/log//system.log.5.gz
/var/log//system.log.1.gz
/var/log//system.log.0.gz
/var/log//system.log.4.gz

$符号表示文件扩展名以gz结尾。


6

我使用这个命令来获取文件夹中文件类型的列表。

find . -type f | egrep -i -E -o "\.{1}\w*$" | sort -su

例子的输出:

.DS_Store
.MP3
.aif
.aiff
.asd
.doc
.flac
.jpg
.m4a
.m4p
.m4r
.mp3
.pdf
.png
.txt
.wav
.wma
.zip

额外福利:使用

find . -type f | egrep -i -E -o "\.{1}\w*$" | sort | uniq -c

您将获得文件计数:
    106 .DS_Store
     35 .MP3
     89 .aif
      5 .aiff
    525 .asd
      1 .doc
     60 .flac
     48 .jpg
    149 .m4a
     11 .m4p
      1 .m4r
  12844 .mp3
      1 .pdf
      5 .png
      9 .txt
    108 .wav
     44 .wma
      2 .zip

5

您需要完成几个步骤。应该像这样:

grep '.*\.zip$'

您需要转义第二个点,这样它就只匹配一个点,而不是任何字符。使用单引号使转义更容易。

您需要在行末使用美元符号来指示您希望“zip”出现在行末。


4
grep -r pattern --include="*.txt" /path/to/dir/

2

以上示例的另一个修复/插件:

# multi-dotted/multiple extensions
grep -oEi "(\\.([A-z0-9])+)+" file.txt

# single dotted
grep -oEi "\\.([A-z0-9])+$" file.txt

这将获取像“.mp3”等文件扩展名。

2
如果您只想在当前文件夹中查找,为什么不使用这个简单的命令而不需要grep呢?
ls *.zip 

2

仅仅回顾一些其他答案。 .* 并不是必要的,如果您正在寻找某个特定的文件扩展名,则最好包括 -i 以使其不区分大小写; 例如如果文件名是HELLO.ZIP。 我认为引号也不是必要的。

grep -i \.zip$

2
在我看来,这是最好的答案,因为它使用最少的字符来获得所需的结果,并且它不区分大小写,这对于通配符类型的功能非常重要。 - Bartekus

2
尝试使用命令: grep -o -E "(\\.([A-z])+)+" 我使用这个命令来获取多点/多扩展名。所以如果输入是hello.tar.gz,那么它会输出.tar.gz。 对于单点,请使用grep -o -E "\\.([A-z])+$"。 已在Cygwin/MingW+MSYS上测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接