任何命令行工具都可以重命名尚未包含字符串或一组字符串的文件,然后包含该字符串?
因此,给定文件夹中的所有文件都应具有high
“高优先级”的名称,但有些文件具有,有些则没有。我不是将其添加到所有文件中,而是如何首先检查文件high
名称中是否包含该文件,如果没有,则将其添加到名称的开头?
答案1
如果您有 GNU Parallel:
parallel mv {} '{= /high/ or $_="high$_" =}' ::: *
答案2
和zsh
:
autoload zmv # best in ~/.zshrc
zmv '^*high*' 'high-$f'
不区分大小写的匹配:
zmv '^*(#i)high*' 'high-$f'
答案3
如果您使用bash
,则该模式!(*high*)
将匹配当前目录中不包含字符串 的所有名称high
(如果extglob
设置了 shell 选项):
$ shopt -s extglob
$ ls
1 2 3 4-high
$ ls -d -- !(*high*)
1 2 3
然后我们可以循环匹配此模式的名称,重命名每个匹配的名称:
shopt -s extglob nullglob
for name in !(*high*); do
[[ ! -f $name ]] && continue
mv -- "$name" "high-$name"
done
这里发生的情况是,我们在循环之前设置了extglob
and nullglob
(使通配模式消失,而不是在模式不匹配时按原样保留)。dotglob
如果您还想重命名隐藏名称,您也可以启用。
然后,循环会跳过任何不引用常规文件的名称(例如,它可能是目录名称),然后high-
在名称前面插入带有 . 的字符串mv
。
--
命令中的是mv
为了避免错误地将任何以破折号开头的文件名解释为一组选项。
在一组测试文件上运行:
$ ls
1 2 3 4-high
只需将上面的代码直接粘贴到 shell 中即可:
$ shopt -s extglob nullglob
$
$ for name in !(*high*); do
> [[ ! -f $name ]] && continue
>
> mv -- "$name" "high-$name"
> done
$ ls
4-high high-1 high-2 high-3
rename
您还可以像这样使用 Perl实用程序:
shopt -s extglob
rename -v 'if (-f) { s/^/high-/ }' -- !(*high*)
这会-f
将此答案中第一个变体中的循环测试移至 Perl 中,但仍使用相同的文件名通配模式来选择要重命名的文件。这-f
使得重命名仅影响常规文件(不影响目录等)
不依赖于 shell 中的扩展通配模式的变体是
rename -v 'if (-f && !/high/) { s/^/high-/ }' -- *
这只是测试名称是否已包含调用high
中的字符串rename
,如果确实发生,则跳过重命名文件。 glob*
选择当前目录中的所有文件(隐藏文件除外)。