可以将锚点 ^ $ 与 ls 一起使用吗?

可以将锚点 ^ $ 与 ls 一起使用吗?

锚点只能与 grep 一起使用还是可以与其他命令一起使用?

例如:

ls -l ^cat

答案1

正则表达式锚点(例如^和 )$仅由以下工具解析实施常用表达。 ls不是这样的工具,所以不,它不能使用它们。然而,从 shell 调用的任何二进制文件都可以使用 shell 通配符,这是一种更简单但功能较弱的基于通配符的搜索机制。

例如,对于名称以 cat 开头的所有文件的列表:

$ ls cat* # lists all files with names which start with 'cat'
$ ls *dog # lists all files with names which end with 'dog'
$ ls d*y  # Lists all files which names which start with 'd' and end
            with 'y', e. g. 'donkey'
$ ls p?g  # Lists all files which start with 'p', have one additional
            character, and end with 'g', e. g. 'pig' and 'pug'

出于通配目的,*表示“零个或多个字符”; while 的?意思是“恰好是一个字符”。

答案2

/bin/ls 程序 - 就像任何其他程序一样 - 不处理*模式。通配符是由Unix shell,而不是它们正在运行的程序。让我解释一下。

ls程序(有几个实现自由软件,就像 GNU 中的那样核心工具包,因此请随意研究其源代码)得到字符串序列(作为第二个参数它是 main函数)已被扩大通过你的外壳(经常bash)。这并不特定于ls,对于您的 shell 启动的每个程序都是如此(通常通过使用您的小路)。

例如,在包含a.c, a.o, b.c, d.c,e.h 文件的目录中,该ls *.c命令被展开通过外壳进入ls a.c b.c d.cso (在这种情况下)ls得到 4 个参数:第一个(索引 0 的)是ls,第二个(索引 1 的)是a.c 等等...,第四个索引 3 的)是d.c。所以ls程序从没见过 *.c外壳是执行(2)- 用四个参数来处理它。由 shell 完成的程序参数扩展称为通配。读全局(7)并了解IFS外壳变量

(请注意,在某些情况下,启动像你这样的文件$HOME/.bashrc可能定义ls为一些别名;然后替换ls\lsorcommand ls/bin/ls以避免此类别名扩展(后两者也可用于规避ls重新定义为功能))

理解扩展发生的一个非常有用的技巧是首先使用自动完成shell 的功能(例如使用您的TAB密钥),或将命令(在您的情况下ls)替换为echo.

所以你真正想要的是具有扩展通配符的 shell。您可以找到几个,并且您可以编写自己的 shell 来执行此操作:

  • 桀骜扩展的通配符

  • 韋斯特有非常不同的扩展(你可以在Scheme中编码)

  • 也试试英语或者克什

  • 或者改编现有的 shell(大多数是免费软件,您可以研究其源代码)来满足您的需求,或者编写您自己的 shell。

FWIW,sash是一个非常简单且小的 shell(有点 bug),其源代码很容易阅读。

与 Posix shell 类似巴什, - 以及其他人,例如- 您可以使用命令替换,例如使用查找(1)(甚至一些ls 管道式的到 some 中grep,就像ls -l $(ls | grep '^foo')这有点无用,并且在某些情况下不起作用,例如带有空格或换行符的文件名,因为与ls -l foo*) 相同。

有些命令会与某些命令进行通配(通常是) 参数或数据,例如查找(1);你可以编写这样的程序,例如使用全局(3)或者词表达式(3)。顺便说一句,您可以使用正则表达式(由正则表达式(1)等等...)也在你的程序中,与正则表达式(3)功能。

请注意,编写自己的 shell 是一项非常有趣的练习,我强烈建议您尝试一次。您需要学习如何使用系统调用(2),例如通过阅读一些书,例如高级Linux编程,并实现您自己的通配符。并理解(在跟踪(1)) 什么系统调用由一些 shell 完成也是值得的。

实际上,如果ls ^cat意味着列出名称以您开头的所有文件,cat只需ls cat*在 shell 中键入命令即可。

顺便说一句,我真的更喜欢zsh作为我的交互的shell(因为恕我直言,它的自动补全效果更好,而且它的扩展扩展确实很有用),但这是一个品味问题,所以 YMMV。但你可以尝试一下(如果你采用它,请使用以下命令更改你的登录 shellchsh(1))。

最后,我建议避免在您自己的文件名中使用空格(以及换行符、控制字符和大多数标点符号)(因此只需使用拉丁字母和数字、点.、百分号%、下划线_、加号+、非开头的破折号-或波浪号~...),但是,在编写供其他人一般使用的 shell 脚本时,请考虑带有空格和奇怪字符的文件名。使用"$@"在这样的脚本中那就更好了。

附言。据传在 Windows(我不知道)上情况有所不同,并且通配符将由一些启动代码来完成crt0或者也许在你的main.你可以阅读操作系统:三个简单的部分以获得更广阔的视野。

答案3

正如其他人所解释的,ls不提供对正则表达式的支持。但是,可以列出与 GNU 特定正则表达式匹配的文件find,如下所示。

首先,您可以使用以下ls操作:

find * -maxdepth 0 -regex "ANY_REGEX" -ls

您还可以使用该-exec操作,它允许您使用任何命令:

find * -maxdepth 0 -regex "ANY_REGEX" -exec ls -la {} \+

最后,您可以find与结合使用xargs,例如:

find * -regex "ANY_REGEX" -print0 | xargs -0 ls -la

默认情况下,find将搜索所有子目录,这就是为什么,为了复制 的行为ls,我添加了过滤器-maxdepth 0

上一个示例中的操作和选项对于处理包含空格的文件名-print0是必需find-0xargs感谢@ilkkachu 指出这一点。

答案4

您可以使用正则表达式“with” ls,但必须将它们传递给grep.

ls | grep ^cat | xargs -r ls -l

Bash 仅通过比较运算符支持正则表达式=~,这需要一个if子句和一个for循环。

for x in *; do if [[ "$x" =~ ^cat ]]; then ls -l "$x"; fi; done

相关内容