-1

I tried to change an string to index to use for an array but I have been unable to get it to work.

This is my file

$ cat file1.txt
101,Harish,BAN
102,Srinu,HYD

And this code:

#!/bin/bash
IFS=','
while read line
do
    DELIM_REMOVE=`echo $line|sed 's/,/ /g'`
    V=($DEL_REMOVE)
    echo ${DELIM_REMOVE}
        for i in "${!V[@]}"; do
            printf 'V[%s] = %s\n' "$i" "${V[i]}"
                echo "${V[i]}"
        done
done < /home/ec2-user/file1.txt
echo "${V[i]}"

I also need to use the dynamically generated variables in loop to another loop.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

2 Answers2

1

Don't use shell loops to process text, use a text processing utility.

awk -F, '{for (i = 0; i < NF; i++) printf "v[%d] = %s\n", i, $(i+1)}' < file1.txt

If you have to use a bash loop, then it would make more sense to write it as:

while IFS=, read -ra v; do
  for i in "${!v[@]}"; do
    printf 'v[%d] = %s\n' "$i" "${v[i]}"
  done
done < file1.txt

With the caveat that if the last field is empty, it will be skipped.

  • It is working fine. Thank you. Need one more help, unable to use Variables outside of the loop. – Harish a Dec 01 '18 at 09:59
  • @Harisha, it does not make sense to use variables outside of the loop, that variable is reset at each iteration, and we get out of the loop when read fails (on end-of-file) at which point $v is set to an empty array. If you want to access the array for the last line of input, you'd need to make a copy within the loop (like last_v=("${v[@]}"). – Stéphane Chazelas Dec 01 '18 at 10:02
  • Can I take any other string like $DATA_V instead of $v. Because I have to use different Variables like DATA_V or DEFAULT_V to call different rows in different files, to store file1.txt rows in $DATA_V[@] and file2.txt in $DEFAULT_V[@], unable to complete my script. Please suggest me. – Harish a Dec 01 '18 at 11:35
  • @Harisha, I don't understand your question. If you need a two-dimensional array (one for lines, one for fields in the lines), you'll need the ksh93 shell, bash only supports one-dimensional (sparse) arrays. Or again, use a proper text-processing tool like awk or perl. – Stéphane Chazelas Dec 01 '18 at 12:58
  • Actually, I am looking for Increment variables dynamically. Please refer the like.https://unix.stackexchange.com/posts/484689/revisions – Harish a Dec 01 '18 at 16:21
  • Chazelas, Please suggest me one example with awk. – Harish a Dec 01 '18 at 17:56
0

There are several issues with your script.

  • The name of the variable in V=($DEL_REMOVE) should be V=($DELIM_REMOVE)
  • You are setting IFS to a comma (,) but you are removing the comma with sed.

By doing those two changes your script starts to do something reasonable.

Making some other changes, your script becomes:

#!/bin/bash

IFS=' '                           # Use the space to split
set -f                            # Avoid globing of values with *,? or []
while read -r line                # read the variable without removing backslash
do
    v=( ${line//,/ } )            # Convert to an array by splitting with the shell.
    for i in "${!v[@]}"; do
            printf 'v[%s] = %s\n' "$i" "${v[i]}"
        done
done < file1.txt

Which will print:

v[0] = 101
v[1] = Harish
v[2] = BAN
v[0] = 102
v[1] = Srinu
v[2] = HYD

Is that what you expected it to do?