Home > database >  how to change words with the same words but with number at the back bash
how to change words with the same words but with number at the back bash

Time:12-14

I have a file for example with the name file.csv and content

adult,REZ
man,BRB
women,SYO
animal,HIJ

and a line that is nor a directory nor a file

file.csv SYO2 REZ3 BRB1

And what I want to do is change the content of the file with the words that are on the line and then get the nth letter of that word with the number at the end of the those words in capital and the output should then be

umo

The code looks like this

#!/bin/bash
filename="$1"
string=""
for i in "${@:2}"
do
words=$(echo "$i" | grep -oE '[A-Z] ')
number=$(echo "$i" | grep -oE '[0-9] ')
string =$(echo "$words|")
numbers =$(echo "$number|")
done
string=${string%|*}
numbers=${numbers%|*}
while IFS= read -r line
do
    line1=$(echo $line | grep -oE $string)
if [[ -n $line1 ]] 
    then 
      echo $line 
    fi
done < $filename

But I get as output

man, BRB
adult, REZ
women, SYO

and the output should be

umo

I don't know how to change the capital words with the numbers that they associated with and the order is not the same anymore. How can I change this or what do I need to add?

CodePudding user response:

You didn't address the substring/character at the requested index anywhere in your try. You have to correlate the key/tag to the offset of the character you want and pull just that character somehow.

I used lookup table.

#!/bin/bash
case $# in 0|1) echo "Use: $0 <infile> [search_pattern1[..search_patternN]]" >&2; exit 1;; esac
declare -A offset=()
for arg in "${@:2}"
do if [[ "$arg" =~ ^([A-Z] )([0-9] )$ ]]
   then offset[${BASH_REMATCH[1]}]=$(( ${BASH_REMATCH[2]} - 1 ))
   else echo "Argument '$arg' is not a valid search prameter."; exit 1
   fi
done
while IFS=, read -r str tag
do [[ -n "${offset[$tag]}" ]] && printf "%s" "${str:${offset[$tag]}:1}"
done < "$1"
echo

I also added some error checking and instructions.

There are a lot of other ways you could do this, such as parallel arrays, scan for your match and use the same index to look up the offset, but you apparently want the records to be parsed and output as they come in, so this is fast and reasonably easy.

CodePudding user response:

Here's an Awk variation. I'm sort of assuming you want to read more than one input line in this format.

while read file args; do
    echo "$args" |
    awk 'NR==FNR { split($0, b, ","); a[b[2]] = b[1]; k[b[2]] =   m; next }
        { delete r; for(i=1; i<=NF;   i) {
            g=$i; sub(/[0-9] $/, "", g);
            n=substr($i, length(g) 1);
            r[k[g]] = substr(a[g], n, 1);
        }
        for(j=1; j<=i; j  ) if (r[j]) printf "%s", r[j];
        printf "\n"}' "$file" -
done

I assume the output should be in the order in which the characters appeared in the input file, which is a complication. The secondary array k keeps track of the input order, and the final for loop then outputs the results in that order.

  •  Tags:  
  • bash
  • Related