如何将ls传送到grep,并删除grep过滤的文件?


33

我想删除主文件中的某些程序包,但是文件名太长(google-chrome-stable_current_i386.deb)。因此,我决定使用命令ls|grep chrome|rm将文件传输到grep,以过滤出chrome文件,然后将其删除。它没有用,所以我想看看我该怎么做。


22
rm -i *chrome*.deb
兰伯特

28
一般来说,我不喜欢人们发布“不要这样做”的答案,但这是我见过的XY问题的最好例子之一。您真正的问题是“我如何快速删除一个长文件名的文件,而无需输入整个内容”,并且有很多不错的方法不涉及ls
重复

5
只需使用find-即可find . -name "*chrome*" -delete
蜘蛛鲍里斯(Boris the Spider)


3
我作为StackExchange用户的两分钱:将来,以更通用的方式提出您的问题,同时提供有关您尝试过的内容的详细信息。“如何删除文件名中带有特定字符串的文件夹中的任何文件?” 可能是表达它的更好方法。顺便说一句,您可以简单地补充一下,您尝试ls通过管道进行连接greprm但无法正常工作。这样,您将获得有关完成任务的“正确”或“最简单”方式的一两个很好的答案,而不是强迫某人就效率低下的解决方案给您一个好的答案。
阿德里安

Answers:


56

这差点让我畏缩。

  1. 您可能要停止将shot弹枪对准您的脚。基本上,任何类型的分析的ls将是更加复杂和容易出错不是像成熟的方法find [...] -exec水珠
  2. 除非有人为您安装了一个巨魔发行版,否则您的外壳已经Tab完成。只需键入rm google并按Tab。如果尚未立即完成,Tab请再次按以查看匹配文件的列表。键入文件名的更多字符以缩小范围,直到完成为止,然后运行命令。
  3. 管道!= 参数。标准输入是二进制数据流,可以异步地将其馈送到命令。参数是用空格分隔的字符串,运行时仅一次将其传递给命令。这些很少互换。

1
抱歉,这似乎是一个n00b问题。我知道一般可以使用,因为所述包装是其中唯一带有“铬”的包装。因此,使用grep只会过滤出一个文件。我对linux来说还很陌生,我已经做了很多bash脚本,但是我还不了解所有内容:P。苛刻,伙计。
SpecialBomb

5
并不是说要苛刻,但外壳是一个苛刻且不可原谅的环境,隐藏在用户友好的表面后面。安全地做事已经很困难了,永远不要安全地,甚至正确做事。
l0b0 2015年

2
@SpecialBomb这是唯一正确的答案。像其他答案一样,解释如何正确对准所说的shot弹枪以干净利落地切断自己的脚,当然不是走的路。要特别注意不要盲目执行rm-这可能是炒发行版的一种更常见的方法。
蜘蛛鲍里斯(Boris the Spider)

@BoristheSpider嘿,我肯定已经炒过Ubuntu两次安装AMD显卡驱动程序了。我已经问过一个问题。AMD一直很可怕,所以我问是否有任何常见的修正或AMD卡上使用Linux进行游戏的更好方法。
SpecialBomb 2015年

34

您还可以将find命令与通配符一起使用:

find . -maxdepth 1 -name '*chrome*' -delete

请注意,“-maxdepth”参数可确保find仅在当前目录中有效,并且不会递归到子目录中。


1
改进建议:(1)使用-iname用于不区分大小写的文件名(b)中管道xargs使用-print0标志find-0标志xargs。使用xargs可以执行“交互式”(确认删除foo?)删除之类的操作。
Christopher Schultz

3
如果使用-exec选项,则无需通过管道传递给xargs:find . -name '*chrome*' -exec rm -i {} +
Johnny

4
这还会递归地删除到子目录中吗?您可能需要指定maxdepth为1
Tyzoid

32

您有正确的想法,只是错过了一些细节。由于您要处理的是STDIN中的列表并rm需要参数,因此需要使用xargs

从而:

ls | grep chrome | xargs rm

应该给你你想要的。

请注意,如果要删除chrome文件以外的所有内容,则可以简单地添加-vgrep语句中。

请注意,对于该问题的其他答案,这可能是完成您想要完成的事情的一种不好的方法。


使用-v,这不会删除匹配文件以外的所有内容chrome吗?我不认为那是OP想要的...
akivajgordon

再看一次,你是正确的。OP希望“过滤掉chrome文件”,但随后要删除它。
约翰

与简单的“ rm -i chrome ” 相比,这似乎不必要地复杂
chander

5
可接受的答案有效,但是请参阅下面的答案,它解释了为什么这是一个坏主意。(在此发表评论仅是为了那些那些一旦看到“接受的”勾号就停下来的人。)
Jim Davis

1
仅当ls输出中没有“怪异”文件名时,可接受的答案才“有效” 。带空格的文件名会破坏这一点。如果有人可以在运行它的目录中构造带有特殊调味料的文件名,这也很危险。正如一个以上的人已经指出的,不要解析ls的输出
Stephen P

11

永远不要解析ls的输出
我的建议是避免解析ls [ 1 ] 的输出,甚至与del命令结合使用时也是如此。由于许多原因,这主要与文件名中允许的意外字符和非常规字符有关。

即使您应该期望属于Linux软件包的文件名“表现得很好”,但如果同一目录中存在其他文件,但您不知道或没有注意到,则仍然可能出现此问题。

最好使用find,将选项卡扩展(开始写名称并按Tab),将文件名扩展 [ 2 ]用作*MyKey*...


快速的解决方案
由于您想选择所有.deb带有“ google”的包(以结尾),因此您可以使用通配符构建请求* *google*.deb并执行简单的操作

rm -i *google*.deb 

会选择中间带有“ google”的每个文件名,该文件名将最终显示在当前目录中。选项(交互式)将提示您进行确认,这是使用参数扩展删除文件时的一个好习惯。.deb-i


溶液接近你尝试的理念,
如果你的目的是要建立的片之后,你的命令行一块,所以你做了ls,以后ls | grep google,和你检查你的输出后,只可以在子shell执行它$(...)

rm -i $(ls | grep google)

甲更快,更危险的方式 [ 3 ],是使用!!

ls | grep google
rm -i $(!!)

它将执行您历史记录中最后完成的命令。如果事先使用启用了shell选项histverify,则可以保护自己免受将要执行的行的视觉控制shopt -s histverify


5
touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;

< rm ... ./0 > ? y
< rm ... ./9 > ? y
< rm ... ./8 > ? y
< rm ... ./7 > ? y
< rm ... ./6 > ? y
< rm ... ./5 > ? y
< rm ... ./4 > ? y
< rm ... ./3 > ? y
< rm ... ./2 > ? y
< rm ... ./1 > ? y
^C

...使用-name '*c*.deb'或适合您的其他样式。


2

rm不接受来自的输入stdin。您需要做类似的事情ls google-chrome* | xargs rm

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.