Replacement with sed + bash

my question seems to be general, but I cannot find the answers.

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

For example, I created the following function:

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

and the following sed command:

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

I found that caracter '&' represents the current found pattern, I would like it to be passed to my bash function, and the whole pattern should be replaced with the found pattern + dateParsed.

Does anyone have any ideas? Thanks

+5
source share
7 answers

You can glue the sed command by completing the one-run section and reopening it.

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

However, unlike other examples, a function from bash cannot return strings; only expose them:

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

you can use the "e" option in the sed command, for example:

 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
source

Agree with Glenn Jackman. If you want to use the 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 starts with a unix timestamp (e.g. 1362407133.936).

+1
source

take it step by step. (you can also use an alternative delimiter, for example, "|" 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 $ can be interpolated

0
source

I would like to know if there is a way to do this too. However, for this particular problem you do not need it. If you surround different date components with () s, you can reference them with \1 \2 , etc. And reformat as you want.

For example, let the converse be 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' 
0
source
 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 
0
source

Bash function inside sed (possibly 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 save the output to a variable:

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

All Articles