Change the contents of a variable using sed (or something similar)

I wrote a BASH file that contains several built-in form loops

for P in {'0.10','0.20', [...] '0.90','1.00'}; do for Q in {'0.10','0.20', [...] ,'0.90','1.00'}; do [...] 

I use these variables as parameters for a command line application, and for creating file names directly in BASH. I would like to create duplicates, say $P_REP=0_10 , which replaces the dot with an underscore without specifying an explicit switch statement for each case or some hardcoded equivalent. (Non-elegant way) that I found is

  • delete the contents of P,Q to a temporary file.
  • replace the period with an underscore with sed 's/./_/ -i .
  • read the file again and load its contents into a new variable.

Therefore, I was wondering if it is possible to run the sed command as directly in the contents of a variable?

+6
source share
4 answers

You can do template replacement directly in bash:

 P_REP=${P/./_} Q_REP=${Q/./_} 

On the bash (1) manual page:

Parameter Extension

${parameter/pattern/string}

Template replacement. The template expands to create the template in the same way as when expanding the path. The parameter expands, and the longest match of the template with its value is replaced by a string. If the pattern starts with / , all pattern matches are replaced with a string. Usually only the first match is replaced. If the pattern starts with # , it must match at the beginning of the extended parameter value. If the pattern starts with % , it must match at the end of the extended parameter value. If the string is NULL, pattern matches are deleted and the pattern / next pattern can be omitted. If the parameter is @ or * , the replacement operation is applied in each positional parameter in turn, and the extension is the resulting list. If the parameter is an array variable, adjusted using @ or * , the replacement operation is applied alternately to each member of the array, and the extension is the resulting list.

+14
source

John Kugelman's answer is suitable for your example, but if you need to process the contents of a variable using a real sed program (or some other arbitrary command), you can do it like this:

 P_REP=$(sed 's/\./_/' <<< "$P") 
+10
source

For loops you can use:

 #!/bin/bash P_REP=$(for P in '0.10' '0.20' '0.90' '1.00'; do echo ${P/./_} ; done) Q_REP=$(for Q in '0.10' '0.20' '0.90' '1.00'; do echo ${Q/./_} ; done) echo ${P_REP[@]} echo ${Q_REP[@]} 
+1
source

For the specific issue you are talking about, use John's suggestion above.

I would say that if you ever need something like this that cannot be solved with the bash template expansion syntax, you don’t need to create temporary files to convert the contents using sed or similar commands. Firstly, you can pass the variable directly to the program as STDIN. Secondly, you can get the output of a command (or its STDOUT, STDERR, or both) directly into a shell variable.

So in your example you would have:

 for P in 0.10 0.20 [...] 0.90 1.00 ; do for Q in 0.10 0.20 [...] 0.90 1.00 ; do P_REP=$( sed 's/\./_/g' <<< "$P" ) Q_REP=$( sed 's/\./_/g' <<< "$Q" ) done done 

Note also that the syntax of the array (that is, { '0.10', '0.20', ...} ) is mostly specific to bash and very few Bash-following. When this is easy to do, you may prefer a more classical approach to shell loops, since I was above that. Your code will then be executed safely in all posix compatible shells.

+1
source

Source: https://habr.com/ru/post/956591/


All Articles