A "clean" awk solution
Some awk
one-shot command with formatted output version if you're interested (although this looks like a job well suited for sed
):
awk -F'\\||,' '{
for (i=1;i<NF+1;i++) {
if ($i ~ /11=.*/) {
split($i, a, "=")
}
if ($i ~ /Order:.*/) {
split($i, b, ":")
}
if ($i ~ /38=.*/) {
split($i, c, "=")
}
}
printf "Orderid-%-10s 38= %-8s Clientid=%s\n", b[2], c[2], a[2]
}' < infile.txt
If you're so keen on not using awk
, sed
or tr
, and absolutely want a shell while loop, please be advised as already said in comments that this is a very bad practice to have. There is extensive explanation of why it is so bad here.
The "don't do it" solution
Now that we have made this little disclaimer, here is a way to achieve your output using only bash string manipulation within a while loop (script form, and of course it only works in bash):
while read line;
do
x=${line#*11=}
x=${x%%|*}
y=${line#*:}
y=${y%%,*}
z=${line#*38=}
z=${z%%|*}
echo "Orderid-$y 38= $z Clientid=$x"
done < infile.txt
In your particular example it works, but please don't do this in a "real life" situation. The basic idea in any shell is: "the least calls to external tools, the better". So ideally if you can do the job in one call like in my awk example, do it. Awk will be loaded once and then the whole job is done in C, which is lightning fast compared to shell.
How string manipulation in bash works in my answer
${string#pattern}
: start from the left-hand side of the string, and deletes the shortest match for patern. So if you put a pattern like *a
for example, everything up to the first "a" character (included) will be removed from your string. If you use the same syntax but with 2 "#", the match for pattern
will become as greedy as possible, and remove everything up to the last "a" character in your string. Example:
$ test="alakazam"; echo ${test#*a}; echo ${test##*a};
lakazam
m
${string%pattern}
: works the same, but from the right-hand side. To illustrate with previous example:
$ test="alakazam"; echo ${test%a*}; echo ${test%%a*};
alakaz
#no output here: the whole string is matched by pattern
grep
? – Michael Vehrs Jan 03 '17 at 16:13grep
pattern would also match111=
. Better use[|,]11=[^|]+
if you're doing it that way. – Kusalananda Jan 03 '17 at 16:22