从命令行替换复杂文本

时间:2010-11-17 21:37:04

标签: regex command-line sed

我想要做的简化示例:

我有一个文件:input.txt,看起来像

a 2 4 b
a 3 8 b
c 9 4 d
a 3 4 8 b

和一个脚本:add.sh,它接受命令行参数并返回它们的总和

我想在input.txt中搜索模式'a (.*) b'的所有实例,其中我将(。*)部分作为命令行参数传递给add.sh。

例如,我想做sed 's/a \(.*\) b/a {add.sh \1} b/g' input.txt之类的事情 (那当然不起作用)。 所以输出应该看起来像

a 6 b
a 11 b
c 9 4 d
a 15 b

最简单的方法是什么?

由于

3 个答案:

答案 0 :(得分:0)

perl -pe 's/a (.*) b/"a ".`add.sh $1`." b"/eg' input.txt

确保add.sh不输出换行符。

答案 1 :(得分:0)

  

如果perl不是一个选项,你可以   脚本它是这样的:

grep -e '^a .* b$' input.txt | sed -e 's/a \(.*\) b/\1/g' | while read LINE; do ./add.sh $LINE; done

我意识到以上并没有解决你的问题,我只关注你的sed表达。

但是,如果您热衷于使用另一个shell脚本解决此问题,它可能看起来像这样:

cat input.txt | while read LINE; do
    if [[ "$LINE" =~ ^a (.*) b$ ]]; then
        echo -n "a "
        add.sh ${BASH_REMATCH[1]}
        echo " b"
    else
        echo $LINE
    fi
done

答案 2 :(得分:0)

如果add.sh是:

#!/bin/sh
arg1=$1
nums=$2
shift 2
for i in $nums
do
    sum=$((sum+i))
done
echo "$arg1 $sum $@"

然后你可以这样做:

sed 's/^\([^ ]* \)\(.*\)\( [^ ]*\)$/\1\"\2\"\3/' input.txt | xargs -L 1 ./add.sh

会在每一行添加数字。要仅为以“a”开头并以“b”结尾的行添加它们,请使用:

sed 's/^a \(.*\) b$/a \"\1\" b/' input.txt | xargs -L 1 ./add.sh

“c 9 4 d”行仍由add.sh处理,但sed命令未添加任何引号,因此脚本仅将“9”视为$2并且所以总和只进行一次,结果为“9”。 “4”被视为$@的其余部分的一部分。