1

I'm writing a shell script, where I have to extract the contents of a file which is of type:

type1|valueA
type2|valueB
type1|valueC
type2|valueD
type3|valueE
....
typen|valueZ.

For each type in column_1, I have a target variable, which concatenates the values of the same type, to get a result like this:

var1=valueA,valueC
var2=valueB,valueD
var3=valueE
.....

Script implements something like this:

var1="HELLO"  
var2="WORLD"  
...  
cat $file | while read record; do  
   #estract column_1 and column_2 from $record    
if [ $column_1 = "tipo1" ]; then  
   var1="$var1, column_2"  ## column_2 = valueB
elif ....  
....  
fi  
done

But when I try to use the value of any of the variables where I chained column_2:

    echo "$var1 - $var2"   

I get the original values:

    HELLO - WORLD.    

Searching the internet, I read that the problem is related to the fact that the pipeline creates a subshell where the actual values are copied.

Is there a way to solve this problem!?

Above all, there is a way that would fit for all types of shells, in fact, this script must run potentially on different shells!? I do not want to use file support on which to write the partial results.

4 Answers 4

3

You don't need to use cat. Piping something into while creates a subshell. When the subshell exits, the values of variables set in the loop are lost (as would be directory changes using cd as another example. Instead, you should redirect your file into the done:

while condition
do
    # do some stuff
done < inputfile

By the way, instead of:

while read record

you can do:

while IFS='|' read -r column1 column2
Sign up to request clarification or add additional context in comments.

Comments

2

BASH FAQ entry #24: "I set variables in a loop. Why do they suddenly disappear after the loop terminates? Or, why can't I pipe data to read?"

1 Comment

All persons who begin writing shell scripts should be required to read through the entire BASH FAQ once, just to head-off the inevitable questions.
0

Oneliner:

for a in `awk "-F|" '{print $1;}' test | sort -u` ; do echo -n "$a =" ; grep -e "^$a" test | awk "-F|" '{ printf(" %s,", $2);}' ; echo "" ; done

Comments

0

Using awk

awk '{a[$1]=a[$1]==""?$2:a[$1] OFS $2}
END{for (i in a) print i"="a[i]}' FS=\| OFS=, file  

type1=valueA,valueC
type2=valueB,valueD
type3=valueE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.