Re: loop with awk

"Cameron Simpson [email protected] [sed-users]" <[email protected]> Sat, 3 Jun 2017 07:52:43 +1000
Newsgroups gmane.editors.sed.user
Message-ID <[email protected]>
On 02Jun2017 21:55, Rachid Mokrani <[email protected]> wrote:
>After some search, this is what I need.
>
>cat A.txt
>Mme;Sylvie;Blue;Paris;FR
>Mr;Dan;Green;New-York;USA
>Mr;David;Allen;Cannes;France

I'm glad you've found a valid solution, and doubly glad that you'd reported it 
back to the list. But it is generally good to provide some of the wider context 
to your question - in your case the reason you are obliged to use a shell loop 
in the solution.

I've got a few remarkes about your solution:

>#!/bin/bash

As is usually the case with all shell script, you do not need to specify bash; 
nothing in your scipt (or in most scripts) makes use of features specific to 
bash. All POSIX systems (== almost all UNIX and Linux systems (and Macs are 
also UNIX)) have /bin/sh, and that is what you should specify for shell 
scripts:

  #!/bin/sh

It will always be there, and it will always have that location. By contrast, 
not all systems have bash and of those which do, not all keep it in /bin.

>while read -r line

Just bear in mind that 'read -r' does strip some leading a trailing whitespace; 
for your needs it is fine, and in most circumstances it is fine, an in the 
shell it if pretty much the best you can do anyway if the shell itself must 
work on each line.

>do
>echo "$line"

Some echoes interpret escapes in the text, such as '\c'. A more robust thing to 
say is this:

  printf '%s\n' "$line"


|awk -F ";" '{print $2"+"$3}' | tr '[:upper:]' '[:lower:]'|awk -v i="$line" '{print i";"$1}'

I am curious as to why you didn't run with the earlier solution from Jim which 
can do this in one line, even if you're using the shell to process each line on 
its own. Since awk can convert things to lower case, why not use that instead 
of stepping through "tr"? Untested example based on Jim's code:

  printf '%s\n' "$line" \
  | awk '-F;' -v 'OFS=;' '{ print $0, tolower($2 "+" $3) }'

This uses several fewer processes, resulting in faster code.

Finally, it is usually good to fold long pipelines as I have above, so that 
each step has its own line. It makes things much easier to read and change.

This folding generally comes in two styles:

  command1 | \
  command2

or:

  command1 \
  | command2

You can see that I prefer the latter; it makes the continued pipeline very 
obvious at the start of the next line; semanticly they are they same, I just 
consider the second more readable.

Cheers,
Cameron Simpson <[email protected]>