sed在bash

时间:2016-03-02 21:41:54

标签: bash awk sed imagemagick

我正在尝试编写一个bash脚本来修剪很久以前扫描的一些旧照片周围的扫描仪空白区域。我有数百张照片,所以我不是手动做的。 Fred的imagemagick脚本无法选择合适的区域。

我不是程序员,所以请不要因我在脚本编写方面的可怕尝试而感到冒犯!

我找到了使用imagemagick的命令组合。

首先我使用模糊滤镜来混淆imagemagick以正确选择照片尺寸:

convert input -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info:

这会将数据吐出如下:

0001.jpeg JPEG 3439x2437 4960x6874+1521+115 8-bit DirectClass 0.070u 0:00.009

然后我使用这些数字进行裁剪,这在我的扫描中非常准确。以下是使用上述数字的示例。

convert inputfile -crop 3439x2437+1521+115 +repage outputfile

我的问题是编写bash文件来浏览图片目录并自动执行该过程。

这是我到目前为止所拥有的:

#!/bin/bash
ls *.jpeg > list
cat list | while read line; do


convert $line -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info: > blurtrim.txt

#need a line to manipulate the output of the above to spit out the crop coordinates for the next command

crop=$(<crop.txt)
convert $line -crop $crop +repage trim$line.jpeg
rm blurtext.txt
rm crop.txt
done
rm list

我不能做的关键是改变第一个imagemagick命令的字符串输出。

该文件沿着以下行:

输入fileformat 1111x2222 3333x4444 + 5555 + 666然后加载一堆废话我不在乎

我的脚本中需要的数字是: 1111X2222 + 5555 + 666

顶部的樱桃是大多数数字是四位数而不是所有数字都是如此,所以我不能依赖它。

关于如何使用sed或者最好使用其他不那么恶魔来获取上述数字的任何想法?

对语法的解释会很好(但是我理解,如果解释是一本书的大小,那么最好省略)。

提前感谢!

3 个答案:

答案 0 :(得分:2)

你不需要解析任何东西! ImageMagick可以使用/node1/node2/node3[condition/task[@name='task1' and @value='abc'] and condition/task[@name='task2' and @value='efg'] and condition/task[@name='task5' and @value='nop']]/id 格式直接告诉您修剪框:

%@

所以,你可以说:

convert image.jpg -virtual-pixel edge -blur 0x15 -fuzz 15% -format "%@" info:
1111x2222+5555+666

好处包括这种方法也适用于Windows,没有trimbox=$(convert image.jpg -virtual-pixel edge -blur 0x15 -fuzz 15% -format "%@" info:) convert image.jpg -crop $trimbox ...

因此,完整的解决方案将是:

sed

答案 1 :(得分:1)

<强>解决方案

这将逐行解析您的文件,提取所需的参数,将它们连接在一起,并将其用作参数值来“裁剪”。对于convert计划:

regex='([0-9]+x[0-9]+) [0-9]+x[0-9]+\+([0-9]+\+[0-9]+)'
while read line
do
    if [[ $line =~ $regex ]]
    then 
        cropParam="${BASH_REMATCH[1]}+${BASH_REMATCH[2]}"
        convert inputfile -crop $cropParam +repage outputfile
    else
        echo "ERROR: Line was not in the expected format ($line)" 
        exit 1;
    fi 
done < blurtrim.txt

<强>解释

regex变量包含一个正则表达式(bash中的正则表达式简介:http://www.tldp.org/LDP/abs/html/x17129.html),它描述了您在问题中描述的数字的格式。模式周围的()部分表示称为捕获组的东西。如果模式匹配,则第一个()中的部分将在bash变量BASH_REMATCH[1]中捕获,而第二个()将在BASH_REMATCH[2]中捕获。 BASH_REMATCH[0]包含整个匹配项,以防您想知道我们为什么从索引1开始。

[[ $line =~ $regex ]]实际上是为我们执行模式匹配算法的。在Bash [[中称为扩展测试命令,而操作符=~称为正则表达式匹配运算符。本文更详细地解释了运算符:http://www.linuxjournal.com/content/bash-regular-expressions

答案 2 :(得分:0)

我会向乔纳森提出一个类似的解决方案:

re='([0-9x]+) [0-9x]+(\+[0-9+]+)'
for file in *.jpeg; do
    output=$(convert "$file" -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info:)
    if [[ $output =~ $re ]]; then
        crop="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
        convert "$file" -crop "$crop" +repage "trim$file.jpeg"
    fi
done

正则表达式捕获包含0-9x范围内的所有字符的组,然后是+后跟数字和+字符的字符。这是一个不太严格的模式,因为它在括号表达式中包含x+,因此在技术上会允许0x9x9x0这样的内容,但我无法想象这会出现基于您向我们展示的输出的问题。

此尝试与原始尝试之间的其他差异是,没有创建临时文件,并且循环在文件列表上运行,而不是使用lsthe parsing of which should generally be avoided in scripts