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

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

问题描述

我正在尝试用 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...

这个想法来自 anubhava 的绝妙回答关于如何更改 sed 中的日期格式?em>.

The idea comes from this superb answer by anubhava on How to change date format in sed?.

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

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