Linux 文件名和文件通配符

5
我有一个文件列表,如下所示:
file000 file001 file002 file003 ... file1100
我该如何匹配所有数字大于800但小于1000的文件呢?我使用的是Linux Bash。
谢谢。
编辑:
实际上,我的文件名如下:
ab869.enc cp936.enc g122345.enc x2022.enc abc8859-14.enc aax5601.enc cp936-1.enc
因此,第一个解决方案无法匹配正确的文件:(
我该如何匹配数字在800到999之间的文件呢?

4
使用魔法?还是你有一种编程语言/Shell在脑海中? - Kirk Woll
5个回答

5

实际上,文件的命名如下: ab869.enc
cp936.enc g122345.enc x2022.enc abc8859-14.enc aax5601.enc所以以上这些不匹配正确的文件 :( 如何匹配文件名中800到999之间的数字?
- amprantino
这将扩展所有数字,无论是否存在这样命名的文件。例如,即使唯一存在的文件是“file999”,它也会扩展为“file801 file802 file803 ...”。花括号扩展不适用于文件名,而仅适用于任意字符串。 - Dan Moulding
@DanMoulding 确定的 - 最初的请求是“我有文件file000到file1100,如何选择file801到file999”,对此它可以正常工作。 - icyrock.com

3
*[89][0-9][0-9].enc

这使用了Bash的“路径扩展”功能(也称为“globbing”)来匹配所有以800到999之间的数字结尾并跟有“.enc”的文件。(这不是一个正则表达式)。

例如,使用上述表达式,您可以在脚本中执行以下操作:

mv *[89][0-9][0-9].enc path/to/destination/

如果您需要它还匹配名为"cp850-1.enc"的文件,那么您需要将表达式更改为:
*[89][0-9][0-9]*.enc

仅供补充,如果您使用的是zsh,您可以将此缩短为[89][0-99]或[0-N],其中N是任何数字。我认为这在bash中可以工作,但它似乎并不是这样。这实际上取决于shell的正则表达式引擎使用的字符集。 - Matthew

1
这提供了一个有趣的扩展,但如果没有目录中的原始文件,则无法进行测试。
echo [a-z,A-Z]*{801..999}[a-z,A-Z]*.enc

在两组括号后面应该加上星号。

0

随便选。

ls | awk -F'[^0-9]*' '800<$2&&$2<1000'  # assuming no filenames start with number

perl -le'/(\d+)/&&800<$1&&$1<1000&&print for<*>'

0

这就是你想要的:

$ ls *{800..999}{,-*}.enc

ab869.enc  abc8859-14.enc  cp936-1.enc  cp936.enc

问题在于你正在使用 abc8859-14.enc,而这并不是你想要的。在这种情况下,egrep 将成为你的好帮手:
$ ls *{800..999}{,-*}.enc | egrep '[^0-9][0-9]{3}(|-.*)\.enc'

如果你想要移动或复制文件,你可能需要将这个表达式放在一个for循环中(在某些情况下,你可能可以使用xargs而不是for循环)。
 for file in $(ls *{800..999}{,-*}.enc | egrep '[^0-9][0-9]{3}(|-.*)\.enc')
 do
      # copy abc859-14.enc to abc859-14.bak
      basefile=$(basename $file .enc)
      cp $file "$basefile.bak"
 done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接