Search code examples
bashawksed

Read one text file line by line, for each line, substitute another text file with all the uppercase string of the line just read


e.g. Read f1.txt line by line, for each line L, substitute f2.txt with all the uppercase string of L.

f1.txt

sone
stwo

f2.txt

st
 sone
  stwo
so

desired output:

st
 SONE
  STWO
so

I tried:

while IFS= read -r line; do
  sed -e 's/\(.*\)/\U\1/' f2.txt
done < f1.txt

Solution

  • One possible interpretation of your requirements, using any awk and reading all of f1.txt into memory but only reading 1 line at a time of f2.txt into memory:

    $ awk 'NR==FNR{a[$0]; next} {for (re in a) gsub(re,toupper(re))} 1' f1.txt f2.txt
    st
     SONE
      STWO
    so
    

    Regarding the attempt in your question, the syntax for that approach would be this, using GNU sed for -i (which I think you need for \U anyway):

    tmp=$(mktemp) &&
    cp -- f2.txt "$tmp" &&
    while read -r line; do
      sed -i 's/'"$line"'/\U&/' "$tmp"
    done < f1.txt &&
    cat "$tmp"
    rm -f "$tmp"
    

    but please read why-is-using-a-shell-loop-to-process-text-considered-bad-practice for some of the reasons not to do that.