Reputation: 531
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.
Upvotes: 1
Views: 24383
Reputation: 45223
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
Upvotes: 0
Reputation: 359865
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
Upvotes: 3
Reputation: 37427
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
Upvotes: 0
Reputation: 798456
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?"
Upvotes: 2