zsh/bash 上不区分大小写的 Glob

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/156916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 20:29:37  来源:igfitidea点击:

Case-insensitive Glob on zsh/bash

linuxbashzshglob

提问by Agnel Kurian

I need to list all files whose names start with 'SomeLongString'. But the case of 'SomeLongString' can vary. How?

我需要列出名称以“SomeLongString”开头的所有文件。但是“SomeLongString”的情况可能会有所不同。如何?

I am using zsh, but a bash solution is also welcome.

我正在使用 zsh,但也欢迎使用 bash 解决方案。

采纳答案by jkramer

ZSH:

ZSH:

$ unsetopt CASE_GLOB

Or, if you don't want to enable case-insensitive globbing in general, you can activate it for only the varying part:

或者,如果您不想启用不区分大小写的通配符,您可以只为不同的部分激活它:

$ print -l (#i)(somelongstring)*

This will match any file that starts with "somelongstring" (in any combination of lower/upper case). The case-insensitive flag applies for everything between the parentheses and can be used multiple times. Read the manual zshexpn(1)for more information.

这将匹配以“somelongstring”开头的任何文件(小写/大写的任意组合)。不区分大小写的标志适用于括号之间的所有内容,并且可以多次使用。阅读手册zshexpn(1)以获取更多信息。

UPDATEAlmost forgot, you have to enable extendend globbing for this to work:

更新几乎忘记了,您必须启用扩展通配符才能使其正常工作:

setopt extendedglob

回答by Jacek Szymański

bash:

重击:

shopt -s nocaseglob

回答by Horst Gutmann

Depending on how deep you want to have this listing, findoffers quite a lot in this regard:

根据您希望此列表的深度,find在这方面提供了很多:

find . -iname 'SomeLongString*' -maxdepth 1

This will only give you the files in the current directory. Important here is the -inameparameter instead of -name.

这只会为您提供当前目录中的文件。这里重要的是-iname参数而不是-name

回答by Modern Hacker


$ function i () {
> shopt -s nocaseglob; $*; shopt -u nocaseglob
> }
$ ls *jtweet*
ls: cannot access *jtweet*: No such file or directory
$ i ls *jtweet*
JTweet.pm  JTweet.pm~  JTweet2.pm  JTweet2.pm~

回答by michael

For completeness (and frankly surprised it's not mentioned yet, even though all the other answers are better and/or "more correct"), obviously one can also use (especially for grepaficionados):

为了完整性(坦率地说,它尚未提及,即使所有其他答案都更好和/或“更正确”),显然也可以使用(特别是对于grep爱好者):

$ ls | egrep -i '^SomeLongString'

One might also stick in a redundant ls -1(that's option "one", not "ell"), but when passed to a pipe, each entry is already going to be one per line, anyway. I'd typically use something like this (vs set) in shell scripts, eg in a for/whileloop: for i in $(ls | grep -i ...). However, the other answer using findwould be preferable & more flexible in that circumstance, because you can, for example, omit directories (or set other restrictions): for i in $(find . -type f -iname 'SomeString*' -print -maxdepth 1)...or even forgo the loop altogether and just use the power of findall by itself, eg: find ... -exec do_stuff {} \; ..., but I do digress (again, for completeness.)

一个人也可能坚持一个多余的ls -1(这是选项“一”,而不是“ell”),但是当传递到管道时,无论如何,每个条目已经是每行一个。我通常会使用这样的事情(VS setShell脚本),例如在for/while循环:for i in $(ls | grep -i ...)。但是,find在这种情况下,使用其他答案会更可取且更灵活,因为例如,您可以省略目录(或设置其他限制):for i in $(find . -type f -iname 'SomeString*' -print -maxdepth 1)...或者甚至完全放弃循环并仅使用findall 本身的功能,例如:find ... -exec do_stuff {} \; ...,但我确实离题了(再次,为了完整性。)