用 sed + bash 函数替换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5777170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:50:43  来源:igfitidea点击:

Substitution with sed + bash function

bashsedsubstitution

提问by Samir Boulil

my question seems to be general, but i can't find any answers.

我的问题似乎很笼统,但我找不到任何答案。

In sed command, how can you replace the substitution pattern by a value returned by a simple bash function.

在 sed 命令中,如何用简单的 bash 函数返回的值替换替换模式。

For instance, I created the following function :

例如,我创建了以下函数:

function parseDates(){
    #Some process here with  (the pattern found)
    return "dateParsed;
}

and the folowing sed command :

和以下 sed 命令:

myCatFile=`sed -e "s/[0-3][0-9]\/[0-1][0-9]\/[0-9][0-9]/& parseDates &\}/p" myfile`

I found that the caracter '&' represents the current pattern found, i'd like it to be passed to my bash function and the whole pattern to be substituted by the pattern found +dateParsed.

我发现字符“&”代表找到的当前模式,我希望将它传递给我的 bash 函数,并且整个模式被找到的模式 +dateParsed 替换。

Does anybody have an idea ? Thanks

有人有想法吗?谢谢

采纳答案by user unknown

You can glue together a sed-command by ending a single-quoted section, and reopening it again.

您可以通过结束单引号部分并再次重新打开来将 sed 命令粘合在一起。

sed -n 's|[0-3][0-9]/[0-1][0-9]/[0-9][0-9]|& '$(parseDates)' &|p' datefile

However, in contrast to other examples, a function in bash can't return strings, only put them out:

但是,与其他示例相比,bash 中的函数不能返回字符串,只能将它们输出:

function parseDates(){
    # Some process here with  (the pattern found)
    echo dateParsed
}

回答by xiaofengmanlou

you can use the "e" option in sed command like this:

您可以在 sed 命令中使用“e”选项,如下所示:

cat t.sh

myecho() {
        echo ">>hello,<<"
}
export -f myecho
sed -e "s/.*/myecho &/e" <<END
ni
END

you can see the result without "e":

你可以看到没有“e”的结果:

cat t.sh

myecho() {
        echo ">>hello,<<"
}
export -f myecho
sed -e "s/.*/myecho &/" <<END
ni
END

回答by Antonio

Agree with Glenn Hymanman. If you want to use bash function in sed, something like this :

同意格伦Hyman曼的观点。如果你想在 sed 中使用 bash 函数,像这样:

sed -rn 's/^([[:digit:].]+)/`date -d @&`/p' file |
while read -r line; do
    eval echo "$line"
done

My file here begins with a unix timestamp (e.g. 1362407133.936).

我这里的文件以 unix 时间戳开头(例如 1362407133.936)。

回答by Roger

Bash function inside sed (maybe for other purposes):

sed 中的 Bash 函数(可能用于其他目的):

multi_stdin(){ #Makes function accepet variable or stdin (via pipe)
    [[ -n "" ]] && echo "$*" || cat -
}

sans_accent(){ 
    multi_stdin "$@" | sed '
        y/àáa???èéê?ìí??òó???ùú?ü/aaaaaaeeeeiiiiooooouuuu/
        y/àá????èéê?ìí??òó???ùú?ü/AAAAAAEEEEIIIIOOOOOUUUU/
        y/?????¢De£??§μYy¥123ao/cCnNBcDdLOoSuYyY123ao/
    '
}

eval $(echo "Rogério Madureira" | sed -n 's#.*#echo & | sans_accent#p')

or

或者

eval $(echo "Rogério Madureira" | sed -n 's#.*#sans_accent &#p')

Rogerio

And if you need to keep the output into a variable:

如果您需要将输出保留为变量:

VAR=$( eval $(echo "Rogério Madureira" | sed -n 's#.*#echo & | desacentua#p') )
echo "$VAR"

回答by ghostdog74

do it step by step. (also you could use an alternate delimiter , such as "|" instead of "/"

一步一步来。(您也可以使用备用分隔符,例如“|”而不是“/”

function parseDates(){
    #Some process here with  (the pattern found)
    return "dateParsed;
}

value=$(parseDates)
sed -n "s|[0-3][0-9]/[0-1][0-9]/[0-9][0-9]|& $value &|p" myfile

Note the use of double quotes instead of single quotes, so that $value can be interpolated

注意使用双引号而不是单引号,这样 $value 可以被插入

回答by drysdam

I'd like to know if there's a way to do this too. However, for this particular problem you don't need it. If you surround the different components of the date with ()s, you can back reference them with \1\2etc and reformat however you want.

我也想知道是否有办法做到这一点。但是,对于这个特定问题,您不需要它。如果您用()s包围日期的不同部分,您可以使用\1\2etc反向引用它们并根据需要重新格式化。

For instance, let's reverse 03/04/1973:

例如,让我们反转 03/04/1973:

echo 03/04/1973 | sed -e 's/\([0-9][0-9]\)\/\([0-9][0-9]\)\/\([0-9][0-9][0-9][0-9]\)/\/\//g'

回答by glenn Hymanman

sed -e 's#[0-3][0-9]/[0-1][0-9]/[0-9][0-9]#& $(parseDates &)#' myfile |
while read -r line; do
    eval echo "$line"
done