简体   繁体   English

匹配 grep 正则表达式中的 X 或 Y

[英]Match X or Y in grep regular expression

I'm trying to run a fairly simple regular expression to clear out some home directories.我正在尝试运行一个相当简单的正则表达式来清除一些主目录。 For background: I'm trying to ask users on my system to clear out their unnecessary files to clear up space on their home directories, so I want to inform users with scripts such as Anaconda / Miniconda installation scripts that they can clear that out.背景:我试图要求我系统上的用户清除他们不必要的文件以清理他们的主目录上的空间,所以我想通过 Anaconda / Miniconda 安装脚本等脚本通知用户,他们可以清除这些文件。

To generate a list of users who might need such an email, I'm trying to run a simple regular expression to list all homedirs that contain such an installation script.为了生成可能需要此类 email 的用户列表,我正在尝试运行一个简单的正则表达式来列出包含此类安装脚本的所有 homedirs。 So my assumption would be that the follwing should suffice:所以我的假设是以下就足够了:

for d in $(ls -d /home/); do
    if $(ls $d | grep -q "(Ana|Mini)conda[23].*\.sh"); then
        echo $d;
    fi;
done;

But after running this, it resulted in nothing at all, sadly.但是在运行这个之后,它完全没有结果,可悲的是。 After a while looking, I noticed that grep does not interpret regular expressions as I would expect it to.看了一会儿,我注意到grep没有像我期望的那样解释正则表达式。 The following:以下:

echo "Lorem ipsum dolor sit amet" | grep "(Lorem|Ipsum) ipsum"

results in no matches at all.结果根本没有匹配。 Which would then explain why the above forloop wouldn't work either.这将解释为什么上面的 forloop 也不起作用。

My question then is: is it possible to match the specified regular expression (Ana|Mini)conda[23].*\.sh , in the same way it matches strings in https://regex101.com/r/yxN61p/1 ?然后我的问题是:是否可以匹配指定的正则表达式(Ana|Mini)conda[23].*\.sh ,就像它匹配https://regex101.com/r/yxN61p/1中的字符串一样? Or is there some other way to find all users who have such a file in their homedir using a simple for-loop in bash?或者是否有其他方法可以使用 bash 中的简单 for 循环来查找在其 homedir 中有此类文件的所有用户?

Short answer: grep defaults to Basic Regular Expressions (BRE), but unescaped () and |简短回答:grep 默认为基本正则表达式 (BRE),但未转义()| are part of Extended Regular Expressions (ERE).是扩展正则表达式 (ERE) 的一部分。 GNU grep, as an extension, supports alternation (which isn't technically part of BRE), but you have to escape \ :作为扩展,GNU grep 支持交替(从技术上讲,这不是 BRE 的一部分),但您必须转义\

grep -q "\(Ana\|Mini\)conda[23].*\.sh"

Or you can indicate that you want to use ERE:或者你可以表明你想使用 ERE:

grep -Eq "(Ana|Mini)conda[23].*\.sh"

Longer answer: this all being said, you don't need grep, and parsing the output of ls comes with a lot of pitfalls .更长的答案:这一切都说了,你不需要 grep,并且解析ls的 output 有很多陷阱 Instead, you can use globs:相反,您可以使用 glob:

printf '%s\n' /home/*/*{Ana,Mini}conda[23]*.sh

should do it, if I understand the intention correctly.如果我正确理解意图,应该这样做。

This uses the fact that printf just repeats its formatting string if supplied with more parameters than formatting directives, printing each file on a separate line.这使用了这样一个事实,即printf如果提供的参数多于格式化指令,则只会重复其格式化字符串,将每个文件打印在单独的行上。

/home/*/*{Ana,Mini}conda[23]*.sh uses brace expansion , ie, it first expands to /home/*/*{Ana,Mini}conda[23]*.sh使用大括号扩展,即它首先扩展为

/home/*/*Anaconda[23]*.sh /home/*/*Miniconda[23]*.sh

and each of those is then expanded with filename expansion .然后每个都用文件名扩展进行扩展 [23] works the same way as in a regular expression; [23]的工作方式与正则表达式相同; * is "zero or more of any character except / ". *是“零个或多个除/之外的任何字符”。

If you don't know how deep in the directory tree the files you're looking for are, you could use globstar and ** :如果您不知道要查找的文件在目录树中的深度,可以使用globstar**

shopt -s globstar
printf '%s\n' /home/**/*{Ana,Mini}conda[23]*.sh

** matches all files and zero or more subdirectories. **匹配所有文件和零个或多个子目录。

Finally, if you want to handle the case where nothing matches, you could set either shopt -s nullglob (expand to nothing if nothing matches) or shopt -s failglob (error if nothing matches).最后,如果你想处理没有匹配的情况,你可以设置shopt -s nullglob (如果没有匹配则扩展为空)或shopt -s failglob (如果没有匹配则错误)。

Shell patterns are described here . Shell 模式在此处描述。

You don't need ls or grep at all for this:为此,您根本不需要lsgrep

shopt -s extglob

for f in /home/*/@(Ana|Mini)conda[23].*.sh; do
  echo "$f"
done

With extglob enabled, @(Ana|Mini) matches either Ana or Mini .启用extglob@(Ana|Mini)匹配AnaMini

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

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