如何通过管道 ls 到 grep,并删除由 grep 过滤的文件?

Spe*_*omb 48 ls grep pipe rm

我想删除我的主文件中的一些包,但文件名太长 ( google-chrome-stable_current_i386.deb)。因此,我决定使用该命令ls|grep chrome|rm将文件通过管道传递给 grep 以过滤掉 chrome 文件,然后将其删除。它不起作用,所以我想看看我如何做到这一点。

l0b*_*0b0 64

这几乎让我畏缩了。

  1. 您可能希望停止将霰弹枪对准您的脚。基本上,任何类型的解析ls都将比已建立的方法(如或globs )复杂且更容易出错find [...] -exec
  2. 除非有人为您安装了 troll 发行版,否则您的 shell 已Tab完成。只需键入rm google并按Tab。如果它没有立即完成,Tab请再次按以查看匹配文件的列表。键入文件名的更多字符以缩小范围,直到完成,然后运行命令。
  3. 管道!=参数。标准输入是一个二进制数据流,它可以异步地提供给一个命令。参数是空格分隔的字符串,在运行时传递给命令一次且仅传递一次。这些很少可以互换。

  • 并不是要苛刻,但外壳是一个严酷无情的环境,隐藏在有点用户友好的表面后面。做事*安全*已经够难了,别介意*安全*甚至*正确*。 (7认同)
  • @SpecialBomb 这是唯一正确的答案。解释如何正确瞄准所述霰弹枪以干净地切断一个人的脚,就像其他答案一样,当然不是要走的路。要特别小心盲目地执行 `rm` - 这可能是一种更常见的方式来炒你的发行版。 (4认同)
  • 对不起,如果它看起来像一个 n00b 问题。我知道一般可以使用,因为所声明的包是唯一一个带有“chrome”的包。因此,使用 grep 只会过滤掉一个文件。我对 linux 很陌生,我已经完成了很多 bash 脚本,但我还不知道一切:P。苛刻,伙计。 (2认同)

Joh*_*ohn 50

你的想法是对的,只是错过了一些细节。由于您正在处理进入 STDIN 的列表并rm需要参数,因此您需要使用xargs.

因此:

ls | grep chrome | xargs rm
Run Code Online (Sandbox Code Playgroud)

应该给你你想要的。

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

请注意,根据此问题的其他答案,这可能是完成您想要完成的任务的一种糟糕方式。

  • 接受的答案有效,但请参阅下面的答案,这解释了为什么这是一个坏主意。(在这里发布此评论只是为了那些看到“已接受”复选标记后立即停止的人。) (5认同)
  • 这个,接受的答案“有效”_仅当 `ls` 输出中没有“奇怪的”文件名时。带空格的文件名会破坏这一点。如果有人可以在您运行它的目录中构造一个带有特殊酱汁的文件名,这也是_危险的_。正如不止一个人已经指出的那样,[不要解析 ls 的输出](http://mywiki.wooledge.org/ParsingLs)! (2认同)

cha*_*der 36

您还可以使用带有通配符的 find 命令:

find . -maxdepth 1 -name '*chrome*' -delete
Run Code Online (Sandbox Code Playgroud)

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

  • 这不会也递归地删除到子目录中吗?您可能需要将 `maxdepth` 指定为 1。 (4认同)
  • 如果您使用 -exec 选项,则无需通过管道传输到 xargs:`find 。-name '*chrome*' -exec rm -i {} +` (3认同)

Has*_*tur 12

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

即使您应该期望属于 Linux 包的文件名将“表现良好”,但如果其他文件存在于同一目录中但您不知道或注意到,这个问题仍然会出现。

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


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

rm -i *google*.deb 
Run Code Online (Sandbox Code Playgroud)

这将选择中间带有“google”的每个文件名,这些文件名将出现在当前目录中。选项(interactive)会提示确认,用参数扩展删除文件的好习惯。.deb-i


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

rm -i $(ls | grep google)
Run Code Online (Sandbox Code Playgroud)

一种更快更危险的方法 [ 3 ],是使用!!

ls | grep google
rm -i $(!!)
Run Code Online (Sandbox Code Playgroud)

这将执行历史记录中完成的最后一个命令。如果您事先histverify使用shopt -s histverify.


mik*_*erv 5

touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;
Run Code Online (Sandbox Code Playgroud)
< 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
Run Code Online (Sandbox Code Playgroud)

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