Home > Software design >  How to replace a string ending with _i with a string starting with i_?
How to replace a string ending with _i with a string starting with i_?

Time:11-12

For example:

input   [TOTAL_CH-1:0]      start_frame_i,  // start of frame

Change to:

input   [TOTAL_CH-1:0]      i_start_frame,  // start of frame

Add on to clarify: There are many different strings are like above.

CodePudding user response:

GNU sed.

cat file.txt | sed -r 's/(\w )_i\b/i_\1/g'

(\w )_i\b

  • (\w )_i matches one or more word character ending with _i and save the string before the _i inside a capturing group(\w ). \b word boundary to ensure it is the end of a word and not to match something like start_frame_iAAA which will result in i_start_frameAAA

i_\1 replace the matched string with, i_ at the beginning and \1 the value which we saved previously inside the capturing group.

CodePudding user response:

I'm going to pretend that your bash tag means that interested in a solution that uses bash.

#!/usr/bin/env bash

while read line; do
        while [[ $line =~ ^(.* )(([a-z_] )_i)([^a-z_].*)$ ]]; do
                line="${BASH_REMATCH[1]}i_${BASH_REMATCH[3]}${BASH_REMATCH[4]}"
        done
        echo "$line"
done

This script walks through stdin reading lines. For each line, it tries to find your source pattern using a bracketed regular expression. Bash stores the bracked subexpressions to the array BASH_REMATCH, so for each time we find it, we reassemble that line. When all replacements are done, we print the line.

You could do the same thing with sed, which is not part of bash but availabe as a tool almost everywhere:

sed 's/\([a-z][a-z_]*\)_i\([^a-z_].*\)/i_\1\2/g' input.txt

This avoids the -r or -E for ERE, which is not portable. BRE regexes are a little more clunky, but have more widespread support, especially in standard tools like sed.

  •  Tags:  
  • bash
  • Related