我想复制名称中没有数字的文件

Rag*_*ora 3 linux command-line rhel cp

这些是所有文件

我想使用 cp 命令使用文件全局复制所有那些没有数值的文件。

复制的文件不应包含 12a、ghf3 和 s2d。

我尝试使用cp [!0-9] *[!0-9] *[!0-9] destination/

Sté*_*las 8

zsh

set -o extendedglob
cp -- ^*<->*(D^/) /path/to/destination/
Run Code Online (Sandbox Code Playgroud)

或者cp -- ^*[0-9]*(D^/) destination/<->匹配一个或多个 ASCII 十进制数字的任何序列(一种<x-y>未设置边界的形式)。

^作为否定运算符,D包括隐藏文件,^/也排除目录类型的文件,无论如何,如果没有// ,这些文件cp将拒绝复制)。-r-R-a

bash与:相同

shopt -s extglob failglob dotglob
cp -- !(*[0123456789]*) /path/to/destination/
Run Code Online (Sandbox Code Playgroud)

!(x)(来自 ksh,需要extglob在读取使用它的代码时进行设置)相当于 zsh 的^xdotglob作为限定符的相当于D,bash 没有相当于 的^/。如果没有,如果没有匹配的文件,failglob则可以复制字面调用的文件。!(*[0123456789]*)

使用 glob 的 POSIX 版本总是非常难以实现,因为没有 glob 限定符或等效的nullglob, failglob(zsh 中的默认行为)或globdot/ dotglob/D限定符,也没有 ksh 风格或 zsh 风格的否定运算符:

set -- [*] *
[ "$1$2" = '[*]*' ] && shift
shift
set -- .[*] .* "$@"
[ "$1$2" = '.[*].*' ] && shift
shift
for file do
  case "$file" in
    (*[0123456789]* | . | ..) ;;
    (*) [ -d "$file" ] && [ ! -L "$file" ] || set -- "$@" "$file";;
  esac
  shift
done
[ "$#" -gt 0 ] && echo cp -- "$@" /path/to/destination/
Run Code Online (Sandbox Code Playgroud)

但你可以使用find

LC_ALL=C find . ! -name . -prune ! -name '*[0-9]*' ! -type d \
  -exec sh -c 'exec cp "$@" /path/to/destination/' sh {} +
Run Code Online (Sandbox Code Playgroud)

LC_ALL=C解决这样的事实:-names*可能无法匹配无法在用户区域设置中解码为文本的字节序列。在C语言环境中,[0-9][0123456789]也是等效的。然而,这意味着这可能会排除以 BIG5 或 GB18030 等字符集编码的文件名,其中某些字符的编码包含 ASCII 数字的字节值。在中国和依赖国之外不太可能。

zsh应该能够使用不完全由文本组成的字符集或文件名来处理语言环境和文件名。bash如果文件名无法完全解码,它也会切换到按字节匹配,这可能会在某些极端情况下导致令人惊讶的结果,包括与上述 BIG5/GB18030 相同的情况。

zsh'[0-9]总是与 相同[0123456789],bash 在 C/POSIX 语言环境之外很少如此。


你的:

cp [!0-9] *[!0-9] *[!0-9] 目的地

不起作用,因为那是:

  • [!0-9]: 文件名是除 0 和 9 之间排序之外的单个字符。如果没有这样的单字母字符,则在bash不使用failglobnullglob启用的情况下,保留[!0-9]的文件名是包含 2 位数字的文件名。
  • *[!0-9]:以 0 到 9 之间排序以外的字符结尾的文件名。1234567X例如,So 会匹配。
  • *[!0-9]同样,我猜这是一个错字,但如果你的意思[!0-9]*是 那就匹配X12345,如果你的意思是*[!0-9]*,那么就会匹配1234X5678

如果您的意思是 regexp 的等价物^[^0-9]*$,或者更好的^[^0123456789]*$*regexp 中的 0 个或多个前面的内容,而不是 glob 中的 0 个或多个字符,那么这将是*([!0123456789])Korn 风格的扩展 glob(bash with 也支持extglob[^0-9]#或zsh 扩展的 glob。另请参阅+([!0123456789])(ksh) 和[^0-9]##(zsh) 以了解 ERE 的等效项+(此处不会产生任何影响,因为文件名无论如何都不能为空)。

另请注意,当您忘记--标记选项结尾时,任何以 开头的文件名-都会被视为选项cp。例如,对于名为-rt..GNU 的文件cp,最终会复制所有其他文件并/path/to/destination递归到父目录!