Search code examples
bashsedgnu-parallel

Append text after a variable in sed


I have some code using GNU-parallel which should replace text in an input file with a series of strings of the form vclist_2d_*.txt where * is a number between 1 and 10000.

FILES=(vclist_2d_*.txt)

parallel -j1  '
    sed -i "s/50pc\/vclist_2d_.*/50pc\/{}'\''/" 1759_input.py
    sed -i "s/schedule_analysis\/vclist_2d_.*/schedule_analysis\/{}'\\_temp\/1759_cs_output.spc''\''/" 1759_input.py
       ' ::: ${FILES[@]}

The first sed command successful replaces whichever vclist_2d_* file is already in 1759_input with the next one in the list FILES as defined by {}. However, the second sed command needs to replace the vclist_2d_* and append to this the text _temp/1759_cs_output.spc'

However, with the code above two things happen:

  1. the vclist name never gets replaced with the next one in the list
  2. the text .temp/1759_cs_output.spc gets appended rather than _temp/1759_cs_output.spc

I've tried several variations of the above none of which were successful. I'm not sure why this works successfully for the first sed but not the second. I thought maybe _ needed escaping but that didn't help.


Solution

  • I don't quite understand what you're doing with the single quotes: I am going to assume that your regex pattern is too greedy and you need to add a quote that got consumed. I'll change .* to [^']0 -- i.e. zero or more non-quote characters.

    You're doing twice as much work as required: put both substitutions into a single sed call

    parallel -j1  ' 
        sed -i "
            s@\(50pc\)/vclist_2d_[^'\'']*@\1/{}@
            s@\(schedule_analysis\)/vclist_2d_[^'\'']*@\1/{}_temp/1759_cs_output.spc@
        " 1759_input.py
    ' ::: "${FILES[@]}"
    

    I used a different delimiter for the s/// command in order to reduce backslashes