我基本上想在 tcsh 中执行以下 bash 命令:
rm !(file1)
谢谢
您可以使用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
.
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 可能有类似的东西。