只列出目录中的数字文件名

12

我有一组数字文件名的文件列表(例如 #.php,##.php 或 ###.php),希望能够一次性地拷贝/移动。

有没有人知道一个可以实现这个目标的 ls 或者 grep 组合命令?

我已经有了这些内容:

ls -al | grep "[0-9].php"
6个回答

8
在Bash中,您可以使用扩展模式匹配:
shopt -s extglob
ls -l +([0-9]).php

这将会找到类似以下的文件:

123.php
9.php

但不是

a.php
2b.php
c3.php

7
像这样修改它:
ls -al | grep -E '^[0-9]+\.php$'

-E 激活扩展正则表达式。

+ 要求前面的组至少出现一次。

\. 转义点号,否则它表示 "任何字符"。

^$ 匹配整个文件名而不是部分。

单引号用于防止变量扩展(因为有 $ 会出错)。


2
不要在脚本中使用 ls 命令,它只适用于交互式使用。 - Philipp
1
@Troubadour:将管道输入到grep中使其成为“脚本”。 - Dennis Williamson
1
@Troubadour:你说得对,但我不认为OP是为了交互式使用而提出这样的问题。此外,许多编写脚本的人也会阅读这些帖子。 - Philipp
1
@Philipp:问题中没有任何暗示是非交互式使用,所以这是一个真正的跳跃。此外,你不能仅仅因为你认为编写脚本的人可能会阅读而将问题变成一个脚本问题。 - Troubadour
2
编辑第一条评论:“不要在脚本或管道中使用ls,它仅用于交互式使用。请参见ParsingLs。” - Dennis Williamson
显示剩余2条评论

4

使用find:

$ find . -regex '^[0-9]+\.php' -exec mv '{}' dest/ ';'

请注意,-regex参数执行的是搜索而不是匹配,这就是为什么需要使用^锚定到开头。此外,假设文件与运行该命令时所在的目录(.)相同。 mv命令中的{}技巧被find替换为找到的文件名。

2
请勿使用此方式,因为文件名中包含空格或换行符时会出现错误。相反,请使用find . -regex '^[0-9]+\.php' -exec mv '{}' dest/ ';'xargs -0 - Philipp
@Philipp:谢谢,这更加健壮。我有印象原帖的文件名集合不包含空格,但是安全起见当然更好。 - unwind
如果模式确实只是 ^[0-9]+\.php$,那么你的原始代码当然不会出问题。然而,我猜很多读者会盲目地修改你的代码以包含其他模式,这可能会导致问题。 - Philipp

2

要么使用find命令(可能与-XXXdepth选项组合使用):

find . -mindepth 1 -maxdepth 1 -regex '^[0-9]+\.php' -exec mv '{}' dest/ ';'

或者使用内置的正则表达式功能:

pattern='^[0-9]+\.php$'
for file in *.php
do
    [[ $file =~ $pattern ]] && echo "$file"
done

不要使用lsgrep命令。


0

以下内容在我的情况下有效:

ls -an

-1

当列出文件时,您可以使用正则表达式:

ls [0-9]*

这是一个简单和极简主义的方法来解决上述问题,但我认为有更好的解决方案

ls -al | grep -E '^[0-9]+\.php$'

如同UncleZeiv在下面解释的那样

2
这当然取决于所使用的shell?例如,bash不会将其视为正则表达式。试一下,你会发现它匹配以数字开头的任何文件名。 - Troubadour
实际上我正在运行bash,它完美地工作了。这太简单了。感谢您的解决方案。我使用了cp [0-9]*。 - gurun8
1
@gurun8:你很幸运没有任何文件名称中包含非数字字符。 - Troubadour
@gurun8,也许这对你有用,但如果存在像123myfile.php这样的文件,它将失败。 - ring bearer
5
这只是偶然发生的,不应该被接受为答案。请试着在包含如 0a.txt 这样的文件的目录中测试它。 - Philipp
1
那是通配符匹配,不是正则表达式。 - Dennis Williamson

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