1

我基本上想在 tcsh 中执行以下 bash 命令:

rm !(file1)

谢谢

4

2 回答 2

2

您可以使用ls -1(这是第一个,而不是小写字母 L)每行列出一个文件,然后使用grep -vx <pattern>排除 ( -v) 与 () 完全-x匹配的行<pattern>,然后xargs将其添加到您的命令中,rm. 例如,

ls -1 | grep -vx file1 | xargs rm

如果您的版本grep不支持该-x选项,您可以使用锚点:

ls -1 | grep -vx '^file1$' | xargs rm

要将其与其他命令一起使用rm,可能不会采用任意数量的参数,请记住添加-n 1选项,xargs以便一个一个地处理参数:

ls -1 | grep -vx '^file1$' | xargs -n 1 rm

我相信您也可以使用find'-name选项通过否定来指定参数来实现这一点,find实用程序本身可能支持诸如 之类的表达式,!(file1)尽管您仍然必须将结果通过管道传输到xargs.

于 2013-06-18T20:59:23.477 回答
1

tcsh 具有^用于 glob 模式的特殊语法(在 csh、sh 或 bash 中不支持)。为 glob 模式添加前缀^会否定它,从而匹配所有与该模式不匹配的文件名。

引用 tcsh 手册:

整个 glob 模式也可以用 '^' 否定:

       > echo *
       bang crash crunch ouch
       > echo ^cr*
       bang ouch

单个文件名不是 glob 模式,因此^前缀不适用于它,但可以通过例如用方括号括住第一个字符来将其转换为一个。

所以这:

rm ^[f]ile1

应该删除当前目录中除file1.

我强烈建议在使用它之前对其进行测试,或者echo首先使用命令:

echo ^[f]ile1

或通过Ctrl-X *在点击之前将模式扩展为文件列表Enter

更新:从那以后,我了解到 bash 支持类似的功能,但语法不同。在 bash 中,匹配与模式!(PATTERN)匹配的任何内容。除非启用了 shell 选项,否则无法识别。与 tcsh 的语法不同,模式可以是单个文件名。这与您的要求无关,但如果您决定切换到 bash,它可能会很有用。extglob^

zsh 可能有类似的东西。

于 2013-06-18T21:55:02.347 回答