如何将条件 OR 引入 grep?例如,为(JPEG 或 JPG)搜索文件类型,然后仅将这些文件发送到照片文件夹中。例如。我知道如何将文件发送到我想要的位置,并获取文件类型,我只需要 grep 部分的一些帮助。
我在 OS X 上,IMO 似乎已经修改/定制了 *nix 实用程序,而不是我在 *nix 环境中习惯的。所以希望答案可以尽可能通用/便携。
jfg*_*956 72
如果你想在grep中引入一个OR,用REGEXP引入它是错误的方式。尝试使用-e
grep 选项:
grep -e PATTERN1 -e PATTERN2 your_file
Run Code Online (Sandbox Code Playgroud)
将匹配带有 PATTERN1 或 PATTERN2 的行。
小智 55
这是另一种方法:
grep "foo\|bar" /path/to/file
Run Code Online (Sandbox Code Playgroud)
这可以找到文本foo
或bar
在file
Gun*_*sen 41
我对正则表达式也很陌生,但由于没有其他人回答我会试一试。管道运算符“|” 用于 OR 运算符。
下面的正则表达式应该让你去某个地方。
.+((JPG)$|(JPEG)$)
Run Code Online (Sandbox Code Playgroud)
(匹配任何一次或多次,最后是“JPG”或“JPEG”)
扩展答案(在了解了 (e)grep 后进行了编辑):假设您有一个文件夹,其中包含以下文件:
test.jpeg, test.JpEg, test.JPEG, test.jpg, test.JPG, test.notimagefile, test.gif
Run Code Online (Sandbox Code Playgroud)
(名字没那么有创意……)
首先,我们首先定义我们对模式的了解:我们知道我们正在寻找名称的结尾。因此,我们使用“$”操作数来定义每一行必须以定义的模式结束。我们知道模式必须是 JPEG 或 JPG。为此,我们使用管道“|” 作为或操作数。我们的模式现在是:
((JPEG)|(JPG))$
Run Code Online (Sandbox Code Playgroud)
(匹配任何以“JPEG”或“JPG”结尾的行)
但是我们看到在这个例子中,唯一的区别是可选的“E”。为此,我们可以使用“?” 操作数(意味着可选)。我们写:
(JP(E)?G)$
Run Code Online (Sandbox Code Playgroud)
(Mach 任何以模式结尾的文件,例如:“J”,后跟“P”,后跟可选的“E”,后跟“G”)。
但是,我们可能还想匹配文件名中带有小写字母的文件。为此,我们引入了字符类“[...]”。意思匹配以下任一。我们写:
([jJ][pP]([eE])?[gG])$
Run Code Online (Sandbox Code Playgroud)
(匹配任何以 at 模式结尾的文件,例如:“j”或“J”,后跟“p”或“P”,后跟可选的“e”或“E”,后跟“g”或“G”) (这也可以使用 grep 中的“-i”选项来完成,但我将此作为 REGEX 中的练习)
最后,由于我们(希望)开始看到一个模式,我们可以省略不必要的括号。由于只有一个可选字母(“E”),我们可以省略这一个。此外,由于文件只有这个模式结束,我们可以省略开始和结束括号。因此我们简单地得到:
[jJ][pP][eE]?[gG]$
Run Code Online (Sandbox Code Playgroud)
最后; 假设您还想查找带有“.gif”文件类型的文件,我们可以将其添加为第二个参数:
([jJ][pP][eE]?[gG])|([gG][iI][fF])$
Run Code Online (Sandbox Code Playgroud)
(在这里,我再次添加了额外的括号以提高可读性/分组。如果它们看起来很混乱,请随意删除它们。)
最后,我使用 ls 和一个管道将所有文件名发送到 (e)grep:
ls | egrep '([jJ][pP][eE]?[gG])|([gG][iI][fF])$'
Run Code Online (Sandbox Code Playgroud)
结果:
test.gif
test.JPG
test.JpEg
test.JPEG
test.jpg
test.JPG
Run Code Online (Sandbox Code Playgroud)
第二次编辑:使用 -i 选项并省略括号,我们可以将其缩短为:
ls | egrep -i 'jpe?g|gif$'
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 12
如果您想按名称匹配文件,grep
则是错误的工具。该grep
实用程序在文件中查找模式;如果您关心的是文件名,则无关紧要。
Shell 通配符模式是按名称匹配文件的方法。在现代 shell 中,通配符模式具有与正则表达式相同的表达能力(即您可以用一个做什么,您可以用另一个做什么),但由于历史原因,它们具有不同的语法。
在 bash 中,您需要首先启用扩展通配符模式,通过输入此行或将其放入您的~/.bashrc
:
shopt -s extglob
Run Code Online (Sandbox Code Playgroud)
然后,您可以将所有.jpg
或.jpeg
文件从当前移动到照片目录,如下所示:
mv *.@(jpg|jpeg) /path/to/photo/directory
Run Code Online (Sandbox Code Playgroud)
甚至
mv *.jp?(e)g /path/to/photo/directory
Run Code Online (Sandbox Code Playgroud)
在zsh中,如果你把setopt ksh_glob
你的~/.zshrc
(或在命令行输入),你可以使用上面的语法,或者你可以写
mv *.(jpg|jpeg) /path/to/photo/directory
mv *.jp(e|)g /path/to/photo/directory
Run Code Online (Sandbox Code Playgroud)
如果要递归复制当前目录及其子目录中的文件,那么在zsh中可以这样写
mv **/*.(jpg|jpeg) /path/to/photo/directory
Run Code Online (Sandbox Code Playgroud)
(注意这里复制foo/bar.jpg
到/path/to/photo/directory/bar.jpg
.)在 bash 版本 4 中,运行shopt -s globstar
,你可以写
mv **/*.@(jpg|jpeg) /path/to/photo/directory
Run Code Online (Sandbox Code Playgroud)
您是否通过运行file $file
和查看输出来获取文件类型?
tk-mbp:~ tkennedy$ file share/rally.jpg
share/rally.jpg: JPEG image data, JFIF standard 1.01
Run Code Online (Sandbox Code Playgroud)
或者,你只是在看文件扩展名?
如果您正在查看 file 命令输出中的实际文件类型:
for file in $(find $dir -type f -exec file {} \; | grep JPEG | cut -d: -f1); do mv $file $photo_dir/ ; done
Run Code Online (Sandbox Code Playgroud)
如果您只是查看文件扩展名,则可以在以下内容中完成所有操作find
:
find $dir -type f -name \*jpg -o -name \*jpeg -o -name \*JPG -o -name \*JPEG -exec mv {} $photo_dir/ \;
Run Code Online (Sandbox Code Playgroud)
如果您只想知道如何将多个参数传递给 grep,您可以通过使用egrep
或grep -E
在 Mac OS X 上做到这一点。
find $dir | grep -E 'jpg|jpeg|JPG|JPEG'
Run Code Online (Sandbox Code Playgroud)
等等。