Bry*_*ead 4 python bash glob argv
我一直在尝试sys.argv[1]使用glob.glob和递归地获取命令行参数()中与glob模式匹配的文件列表os.walk.问题是,bash(以及它看起来很多其他shell)会自动将glob模式扩展为文件名.
标准的unix程序(例如grep -R)如何执行此操作?我意识到他们不是在python中,但如果这种情况发生在shell级别,那应该不重要,对吧?有没有办法让脚本告诉shell不自动扩展glob模式?它似乎set -f会禁用通配,但我不知道如何尽早运行,可以这么说.
我见过使用Glob()在Python中递归查找文件?,但这并不包括实际从命令行参数获取glob模式.
谢谢!
编辑:
grep-like perl脚本ack接受perl正则表达式作为其参数之一.因此,ack .*打印出每个文件的每一行.但是.*应该扩展到目录中的所有隐藏文件.我试过阅读剧本,但我不知道perl; 它怎么能这样做?
shell甚至在考虑调用命令之前执行glob扩展.诸如grep之类的程序不会做任何事情来阻止通配:它们不能.你,因为这些程序的调用者,必须告诉你要传递的特殊字符,如外壳*,并?以该程序,而不是让壳解释它们.你可以把它们放在引号内:
grep -E 'ba(na)* split' *.txt
Run Code Online (Sandbox Code Playgroud)
(寻找ba split,bana split等等,在一个名为<东西>中的所有文件.txt),在这种情况下,无论是单引号或双引号会做的伎俩.在单引号之间,shell不会扩展.双引号之间,$,`并且\还在解释.您还可以通过在反斜杠前面加上单个字符来保护shell扩展.这不仅是需要保护的通配符; 例如,在上面,模式中的空格是引号,因此它是参数的一部分grep而不是参数分隔符.编写上述代码段的其他方法包括
grep -E "ba(na)* split" *.txt
grep -E ba\(na\)\*\ split *.txt
Run Code Online (Sandbox Code Playgroud)
对于大多数shell,如果参数包含通配符但模式与任何文件都不匹配,则模式保持不变并传递给基础命令.所以像这样的命令
grep b[an]*a *.txt
Run Code Online (Sandbox Code Playgroud)
具有不同的效果取决于系统上存在的文件.如果当前目录不包含名称以其开头的任何文件b,则该命令将搜索b[an]*a名称匹配的文件中的模式*.txt.如果当前目录包含命名的文件baclava,bnm并且hello.txt,该命令将扩展到grep baclava bnm hello.txt,所以它搜索模式baclava中的两个文件bnm和hello.txt.不用说,在脚本中依赖它是一个坏主意; 在命令行上,它偶尔可以节省打字,但这样做很危险.
当您ack .*在不包含点文件的目录中运行时,shell将运行ack . ...然后,该ack命令的行为是递归地打印出(当前目录的父级)下的所有文件中的所有非空行(模式.:匹配任何一个字符)...与之对比ack '.*',搜索.*当前目录及其子目录中的模式(匹配任何内容)(由于ack您未传递任何文件名参数时的行为).