使用捕获组作为参数,用bash命令的输出替换sed [英] Sed replace with the output of a bash command using capture group as argument

查看:133
本文介绍了使用捕获组作为参数,用bash命令的输出替换sed的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用sed进行base64替换.

I'm trying to make some base64 substitution with sed.

我想做的是这样:

sed -i "s|\(some\)\(pattern\)|\1 $(echo "\2" | base64 -d)|g" myFile

用英语是:

  • 数学模式
  • 捕获组
  • 在bash命令中使用捕获的组
  • 使用此命令的输出作为替换字符串

到目前为止,我的命令不起作用,因为\2仅由sed知道,而不能由我正在调用的bash命令知道.

So far my command doesn't work since \2 is known only by sed and not by the bash command I'm calling.

对于将捕获组传递给要使用其输出的命令,我有什么优雅的解决方案?

What elegant solution to I have to pass a capture group to a command of which I want to use the output?

修改

这是我要尝试做的一个最小示例:

Here is a minimal example of what I'm trying to do:

我有以下文件:

someline
someline
Base64Expression stringValue="Zm9v"
someline
Base64Expression stringValue="YmFy"

我想用纯文本替换base64:

And I want to replace the base64 by plain text:

someline
someline
Base64Expression stringValue="foo"
someline
Base64Expression stringValue="bar"

将来,我将不得不执行向后操作(在解码文件的base64中编码字符串)

In the future I'll have to do the backward operation (encoding string in base64 on the decoded file)

我已经开始使用awk,但是我可以用sed使其变得更简单(也更优雅).到目前为止,awk有了这个(其中$bundle是我正在编辑的文件):

I've started using awk but I though it could get simpler (and much more elegant) with sed. So far with awk I have this (where $bundle is the file I'm editing):

#For each line containing "Base64Expression"
#Put in the array $substitutions[]:
# The number of the line (NR)
# The encoded expression ($2)
# The decoded expression (x)
substitutions=($(awk -v bd=$bundle '
    BEGIN {
        # Change the separator from default
        FS="""
        ORS=","
        OFS=","
    }
    /Base64Expression/ {
        #Decode the base64 lines
        cmd="echo -ne \""$2"\" | base64 -d"
        cmd | getline x

        if ( (cmd | getline) == 0 ){
            print NR, $2, x
        }
    }
' $bundle))

# Substitute the encoded expressions by the decoded ones
# Use the entries of the array 3 by 3
# Create a sed command which takes the lines numbers
for ((i=0; i<${#substitutions[@]}; i+=3))
do
    # Do the substitution only if the string is not empty
    # Allows to handle properly the empty variables
    if [ ${substitutions[$((i+1))]} ]
    then
        sed -i -e "${substitutions[$i]}s#${substitutions[$((i+1))]}#${substitutions[$((i+2))]}#" $bundle
    fi
done

推荐答案

您可以在GNU sed中使用e将替换字符串传递给shell进行评估.这样,您可以说:

You can use e in GNU sed to pass the substitution string to a shell for evaluation. This way, you can say:

printf "%s %s" "something" "\1"

\1包含捕获的组的位置.在一起:

Where \1 holds a captured group. All together:

$ sed -r 's#match_([0-9]*).*#printf "%s %s" "something" "\1"#e' <<< "match_555 hello"
something 555

当您要对捕获的组执行某些shell动作时(例如在这种情况下),这很方便.

This comes handy when you want to perform some shell action with a captured group, like in this case.

因此,让我们捕获行的第一部分,然后是需要编码的部分,最后是其余部分.完成此操作后,让我们用printf打印这些片段,从而触发base64 -d在第二个切片上的使用:

So, let's capture the first part of the line, then the part that needs to be encoded and finally the rest. Once this is done, let's print those pieces back with printf triggering the usage of base64 -d against the second slice:

$ sed -r '/^Base64/s#(.*;)([^\&]*)(&.*)# printf "%s%s%s" "\1" $(echo "\2" | base64 -d) "\3";#e' file
someline
someline
Base64Expression stringValue=&quot;foo&quot;
someline
Base64Expression stringValue=&quot;bar&quot;

逐步:

sed -r '/^Base64/s#(.*;)([^\&]*)(&.*)# printf "%s%s%s" "\1" $(echo "\2" | base64 -d) "\3";#e' file
#        ^^^^^^^    ^^^  ^^^^^^  ^^^                        ^^^^^^^^^^^^^^^^^^^^^^^^       ^
#           |   first part  |   the rest                encode the 2nd captured group      |
#           |               |                                                              |
#           |           important part                                      execute the command
#           |
# on lines starting with Base64, do...

这个想法来自于如何更改sed中的日期格式的 anubhava的精妙答案.

这篇关于使用捕获组作为参数,用bash命令的输出替换sed的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆