Substitution with sed + bash function

时间秒杀一切 提交于 2019-12-06 02:06:36

问题


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.

For instance, I created the following function :

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

and the folowing sed command :

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.

Does anybody have an idea ? Thanks


回答1:


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

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:

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



回答2:


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

cat t.sh

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

you can see the result without "e":

cat t.sh

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



回答3:


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

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).




回答4:


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

function parseDates(){
    #Some process here with $1 (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




回答5:


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 \2 etc and reformat however you want.

For instance, let's reverse 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]\)/\3\/\2\/\1/g'



回答6:


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



回答7:


Bash function inside sed (maybe for other purposes):

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

sans_accent(){ 
    multi_stdin "$@" | sed '
        y/àáâãäåèéêëìíîïòóôõöùúûü/aaaaaaeeeeiiiiooooouuuu/
        y/ÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜ/AAAAAAEEEEIIIIOOOOOUUUU/
        y/çÇñÑߢÐð£Øø§µÝý¥¹²³ªº/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"


来源:https://stackoverflow.com/questions/5777170/substitution-with-sed-bash-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!