使用带有正则表达式的find来执行for循环

时间:2016-02-06 07:35:32

标签: linux bash unix find

我正在尝试查找所有带有模式q[0-9]+[0-9]+[a-z]+.JPG的文件,并且对于找到的每个文件执行convert(imagemagick)执行fooq[0-9]+[0-9]+[a-z]+.pdf的输出

这是我的剧本:

#!/bin/bash

i=1
find . -type f -regex './q[0-9]+[0-9]+[a-z]+.JPG' -exec bash -c 'for j; do convert "$j" q$((i++)).pdf; done' "$targetfile" {} +

找不到文件,即使我将命令更改为:

#!/bin/bash

i=1
find . -type f -regex './q[0-9a-z]*.JPG' -exec bash -c 'for j; do convert "$j" q$((i++)).pdf; done' "$targetfile" {} +

测试find命令(在这种情况下有效),文件未按正确顺序转换。看起来我需要在某处插入sort,但我不知道该怎么做。文件名如下:

q1a.JPG
q7b.JPG
q11g.JPG

,输出文件名应如下所示:

fooq1a.pdf
fooq7b.pdf
fooq11g.pdf

我将如何

  1. 创建正确的正则表达式
  2. sort添加到我的脚本
  3. 如果您有比我更好的解决方案,请随时分享。干杯!

1 个答案:

答案 0 :(得分:0)

默认情况下regex使用的find基本上是 EMACS 正则表达式。如果需要,您可以使用-regextype <type>选项调整正则表达式的类型find。但是,在给定文件名的情况下,只要文件名相对一致,就可以使用默认的正则表达式使用简单的模式匹配。要处理示例中的文件名,您可以执行以下操作:

while read -r name; do 
    fname=$(basename "$name")
    convert "$name" "$(dirname "$name")/foo${fname/JPG/pdf}"
done < <(find ./ -type f -name 'q[0-9]*JPG')

(这假设JPG扩展名,并且您没有JPG作为文件名的一部分再次出现)

例如,要输出正在发生的内容,您只需替换echoprintf代替convert进行测试即可。一个简短的例子是:

#!/bin/bash

while read -r name; do 
    fname=$(basename "$name")
    printf "convert %s %s\n" "$name" "$(dirname "$name")/foo${fname/JPG/pdf}"
done < <(find ./ -type f -name 'q[0-9]*JPG')

<强>输出

$ bash cvttopdf.sh
convert ./q11g.JPG ./fooq11g.pdf
convert ./q1a.JPG ./fooq1a.pdf
convert ./q7b.JPG ./fooq7b.pdf

sort,您无需sort作为转化的一部分。要按排序顺序查看文件,您只需按照排序顺序查看,使用ls或更精细sort调用的常规工具之前或之后。如果你有其他需要进行转换的一部分作为转换的一部分,请放弃并注意,我会尝试进一步提供帮助,我有点困惑,因为它将jpeg转换为pdf的目的是什么? / p>