1

I am attempting to format two pieces of data from my awk script. Here is a piece of my raw data

Mike:James:314849866:[email protected]:5059358554:NM:8830:Johnson:Rd:Albuquerque:87122 

There are a total of nine lines like this. I have formatted it in this manner

Mike James, 314849866
8830 Johnson Rd
Albuquerque, NM 87122
[email protected]
5059358554

using this code:

cat rawadd | awk -F:  ' NR == 1,NR == 9 {print $1 " " $2 ", " $3 "\n" $7 " " $8 " " $9 "\n" $10 ", " $6 " " $11 "\n" $4 "\n" $5

I would like to format the phone number, the fifth line like (505)935-8554. So I created a new variable $tel, and replaced it with the $5 variable that I extracted from the rawadd file.

Here is what that new code looks like:

tel=`"(${5:0:3}) ${5:3:3}-${5:6:4}"`


cat rawadd | awk -F:  ' NR == 1,NR == 9 {print $1 " " $2 ", " $3 "\n" $7 " " $8 " " $9 "\n" $10 ", " $6 " " $11 "\n" $4 "\n" $tel "\n"}';

But my output is coming out like this

Mike James, 314849866
8830 Johnson Rd
Albuquerque, NM 87122
[email protected]
Mike:James:314849866:[email protected]:5059358554:NM:8830:Johnson:Rd:Albuquerque:87122

On the fifth line it just prints the actual line input, and not the formatted telephone number. I was hoping that I might add the formatting directly into the awk command, but cannot figure out a way. I would also like to format the Id number on the first line to be 314-84-9866. Any help would be great.

Thank you

2
  • your $tel variable is not visible in awk, within single quotes bash variables are not substituted. Even it was visible the way you coded doesn't work in awk. Instead you have to use "(" substr($5,1,3) ")" .. etc in the awk script. Commented Nov 28, 2017 at 0:15
  • Google UUOC and then consider what value cat rawadd is adding. Commented Nov 28, 2017 at 2:14

2 Answers 2

2

Very similar to @karakfas answer but will work in any awk, uses a choice of OFS that I think better represents your real output fields, and will only process the first 9 input lines, like in your original script:

$ cat tst.awk
BEGIN { FS=":"; OFS=", " }
{
    print $1 " " $2, substr($3,1,3) "-" substr($3,4,2) "-" substr($3,6)
    print $7 " " $8 " " $9
    print $10, $6 " " $11
    print $4
    print "(" substr($5,1,3) ")" substr($5,4,3) "-" substr($5,7)
}
NR==9 { exit }

$ awk -f tst.awk file
Mike James, 314-84-9866
8830 Johnson Rd
Albuquerque, NM 87122
[email protected]
(505)935-8554

The first problem you were having with your tel variable is that when you write:

tel=7
awk '{print $tel}'

you actually have 2 completely different variables, a shell variable named tel created by tel=7 in the shell script, and an awk variable also named tel created by print $tel in the awk script and completely unrelated to the shell variable of the same name.

The second problem you were having is that to access the contents of an awk variable you just use the variable name, just like you would in C, you do not prepend it with a $ like you would in shell.

The third problem you were having is that since the awk variable tel is unset it gets the value zero-or-null (all awk variables are of type numeric-string - google that) and so when you use $tel that's the same as if you said $0 whose contents are the entire input line (record).

All of those together are why you were getting the input line reproduced in your output.

The syntax to do what you were trying to do would be:

tel=7
awk -v tel="$tel" '{print tel}'

where -v tel="$tel" is initializing an awk variable named tel with the contents of the shell variable also named tel. More clearly:

shelltel=7
awk -v awktel="$shelltel" '{print awktel}'

It's very important to understand that awk is not shell - it's a completely separate tool with it's own scope and a language whose syntax is much more similar to C than to shell.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Ed, I will go this route!
0

Here is one solution with gawk,

awk -F: '{
          print $1, $2 ",", gensub(/(...)(..)(....)/,"\\1-\\2-\\3",1,$3);
          print $7, $8, $9; 
          print $10 ",", $6, $11; 
          print $4
          print gensub(/(...)(...)(....)/,"(\\1)\\2-\\3",1,$5)
         }' file

will give

Mike James, 314-84-9866
8830 Johnson Rd
Albuquerque, NM 87122 
[email protected]
(505)935-8554

your NR==1 ... didn't make any sense to me. Perhaps you have some reason but need to explain.

2 Comments

NR ==1, NR ==9 is reading in lines one - nine of the file and formatting them based on the selections I have made. Everything works fine, except for the part with formatting the telephone number and ID. I would like to try and work out the command that I have, but It appears that I cannot add new variables into this awk command, so I may need to utilize your method after all. Unless my comment makes any sense to you. Thank you
@EdMorton Morton, If you look at my fist command, Iuse just the "$5" to display the phone number. I was hoping to do all of my code as efficient as possible, so I was hoping that I could reformat the telephone number in the variable "$tel" which I would then insert into my awk command. I am realizing that this would not be the the best method. Karakfa seems to have provided the most efficient use of awk for my purpose.

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.