获取 ls 命令结果的补码

获取 ls 命令结果的补码

假设我有一个包含多个文件的目录,所有这些文件都是二进制文件(没有声明扩展名的文件)和源文件(.c扩展名)。我这样做:

$ ls

并得到:

README.md hello-world.c hello-world get-name.c get-name

我只想列出具有特定扩展名的文件(例如.c.md),我这样做:

ls *.c *.md

没关系!

但是如果现在我想删除所有文件怎么办不要有一个.cor.md扩展名,我该怎么做?

我知道如何处理我知道扩展名的文件,例如:

ls *.c *.md | xargs rm

但是我如何告诉命令行删除那些文件符合我的标准吗?

答案1

使用find

find -maxdepth 1 ! -name "*.c" -print0 | xargs -0 ...

请注意-maxdepth, 、-print0-r-0在一些实现中可以找到(由 GNU /find引入),但 POSIX 并未指定。另一种方法是,正如 Stéphane 在他的评论中提到的,使用find 的操作 - 记住使用表单,因为它大大减少了调用的次数(它必须允许将文件名放在末尾的语法,否则你需要将其包装在一个调用中)。findxargs-exec-exec command {} +commandcommandsh -c

或者grep输出ls

ls | grep -v "\.c$" | xargs ...

您可以使用正则表达式过滤多个扩展名:

... | grep -v "\.\(c\|md\)$" | ...

使用扩展的正则表达式:

... | grep -Ev "\.(c|md)$" | ...

使用固定字符串选项(仅在文件名末尾不匹配!):

... | grep -vF ".c
.md" | ...

或者通过链接更多greps:

... | grep -v "\.c$" | grep -v "\.md$" | ...

也就是说,find这可能是最好的选择,因为使用该-print0选项,它可以处理文件名中可能需要转义的所有可能字符(前提是您的findxargs能够使用以 NULL 结尾的字符串 - 例如 GNU 工具是)。

答案2

在 中ksh,您可以使用:

rm -- !(*.c|*.md)

这些通配扩展也可以在bashaftershopt -s extglob和 in zshafter中使用setopt kshglob

以下是 zsh 本机等效项:

setopt extended_glob
rm -- ^(*.c|*.md)

!extglob 中的 是“not” 。对于您的原始命令,最好这样写:

rm -- *.c *.md

解析 的输出ls是不可靠的,并且会在某些文件名上中断。请参阅 bash wiki解析 ls

相关内容