简体   繁体   English

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

[英]Case-insensitive Glob on zsh/bash

I need to list all files whose names start with 'SomeLongString'.我需要列出名称以“SomeLongString”开头的所有文件。 But the case of 'SomeLongString' can vary.但是“SomeLongString”的情况可能会有所不同。 How?如何?

I am using zsh, but a bash solution is also welcome.我正在使用 zsh,但也欢迎使用 bash 解决方案。

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).这将匹配任何以“somelongstring”开头的文件(小写/大写的任意组合)。 The case-insensitive flag applies for everything between the parentheses and can be used multiple times.不区分大小写标志适用于括号之间的所有内容,并且可以多次使用。 Read the manual zshexpn(1) for more information.阅读手册zshexpn(1)了解更多信息。

UPDATE Almost forgot, you have to enable extendend globbing for this to work:更新差点忘了,您必须启用扩展通配才能使其工作:

setopt extendedglob

重击:

shopt -s nocaseglob

Depending on how deep you want to have this listing, find offers 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 -iname parameter instead of -name .这里重要的是-iname参数而不是-name


$ 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~

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 grep aficionados):为了完整性(坦率地说,它还没有被提及,尽管所有其他答案都更好和/或“更正确”),显然也可以使用(特别是对于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.也可能会插入一个冗余的ls -1 (这是选项“one”,而不是“ell”),但是当传递给管道时,无论如何,每个条目都将是每行一个。 I'd typically use something like this (vs set ) in shell scripts, eg in a for / while loop: for i in $(ls | grep -i ...) .我通常会在 shell 脚本中使用这样的东西(vs set ),例如在for / while循环中: for i in $(ls | grep -i ...) However, the other answer using find would 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 find all by itself, eg: find ... -exec do_stuff {} \; ...但是,在这种情况下,使用find的另一个答案会更可取且更灵活,因为例如,您可以省略目录(或设置其他限制): for i in $(find . -type f -iname 'SomeString*' -print -maxdepth 1)...甚至完全放弃循环,只使用find all 本身的功能,例如: find ... -exec do_stuff {} \; ... find ... -exec do_stuff {} \; ... , but I do digress (again, for completeness.) find ... -exec do_stuff {} \; ... ,但我确实离题了(再次,为了完整性。)

For completeness, a long, full solution (creating thumbnails from a list of camera images):为了完整起见,一个长而完整的解决方案(从相机图像列表创建缩略图):

_shopt="$( shopt -p )"
shopt -s nocaseglob
for f in *.jpg; do
    convert "$f" -auto-orient -resize "1280x1280>" -sharpen 8 jpeg:"$( basename "$f" ".${f##*.}" ).shelf.jpg"
done
eval "$_shopt"

Since we don't know exact extension case (.jpg or .JPG), we create it from the name itself by stripping the prefix up to (and including) the last dot.由于我们不知道确切的扩展大小写(.jpg 或 .JPG),因此我们从名称本身通过剥离前缀直到(并包括)最后一个点来创建它。 The -auto-orient option will take care of image orientation so that thumbnails would be viewed correctly on any device. -auto-orient 选项将处理图像方向,以便在任何设备上都能正确查看缩略图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM