1834340 Members
2178 Online
110066 Solutions
New Discussion

Quick awk question

 
SOLVED
Go to solution
someone_4
Honored Contributor

Quick awk question

i have an file with
aaa ab abc abd abcde abds # space is tab
and a script

#!/usr/bin/sh
for user in $(awk -F"\t" '{ print $2 }' input)
do
echo $user
done

but the output is
ab
abc
abd
abcde
abds

when I run it from the command line it comes out the way I want it
ab abc abd abcde abds

Two questions
1. Why does the format change?
2. How do I fix it? I thought it was a path issue but it seems that is not the case.
3. $(awk -F"\t" '{ print $2 }' input | sort)
doest not work in the script either but it works from the command line.


Thanks
Richard
17 REPLIES 17
Gavin Clarke
Trusted Contributor

Re: Quick awk question

echo \c $user
?
Geoff Wild
Honored Contributor

Re: Quick awk question

You don't need the -F"\t" - will work with space or tab.

$2 is ab - that is all that should be printed....

Rgds...Geoff
Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
TwoProc
Honored Contributor

Re: Quick awk question

This might fix it.

I can't test it for you b/c I can't get that awk expression to work at all. But assuming that it works (you got output in your example), the easiest way I know to make multiline output "collect" into a single line is to define the whole thing as a function, see below.


#!/usr/bin/sh
awkit()
{
for user in $(awk -F"\t" '{ print $2 }' input)
do
echo $user
done
}
awkit $1 $2 $3 $4 $5 $6 $7 $8 $9

We are the people our parents warned us about --Jimmy Buffett
TwoProc
Honored Contributor

Re: Quick awk question

BTW, when I "fix" the awk expression, I get what Geoff got - just "ab".
We are the people our parents warned us about --Jimmy Buffett
A. Clay Stephenson
Acclaimed Contributor

Re: Quick awk question

If I assume that your file is named "input" and if it consists of a single line of separated fields then you should only have a single line of output "ab" because the awk will only return $2 from 1 line of input.

Since you didn't indicate what you wanted it to do I don't know how to tell you to fix it.

I suspect the file "input" is not exactly as you described. Please post this output:

od -Ad -tc -v input

If it ain't broke, I can fix that.
Hein van den Heuvel
Honored Contributor

Re: Quick awk question


Richard,

Is your input file a single line with tab-seperated columns?
Or does it have multipel lines.

I have the feeling you need something along the lines of:


awk '{i=0; while (i++ < NF) {print $i}}' input | sort

hth,
Hein.
someone_4
Honored Contributor

Re: Quick awk question

Hi everyone I guess this is not a quick awk question :)

FIle tab-seperated
sedi6s sedi6a sedi6s ssdi0s zabcd9a abcder1
sedi6a sedi6z sedi6a ssdi0d zabcd9x abcder9

# od -Ad -tc -v input
0000000 s e d i 6 s \t s e d i 6 a s e
0000016 d i 6 s s s d i 0 s z a b c
0000032 d 9 a a b c d e r 1 \n s e d i
0000048 6 a \t s e d i 6 z s e d i 6 a
0000064 s s d i 0 d z a b c d 9 x
0000080 a b c d e r 9 \n
0000088

This is the output from the command line
#awk -F"\t" '{ print $2 }' input
sedi6a sedi6s ssdi0s zabcd9a abcder1
sedi6z sedi6a ssdi0d zabcd9x abcder9

and would like the same format out of the script.

Thanks
Richard
someone_4
Honored Contributor

Re: Quick awk question

The tab didnt show in my post so I will replace where the tab with \t.

FIle tab-seperated
sedi6s\t sedi6a sedi6s ssdi0s zabcd9a abcder1
sedi6a\t sedi6z sedi6a ssdi0d zabcd9x abcder9
Geoff Wild
Honored Contributor

Re: Quick awk question

I really can't see how you are getting that...on my system, command line or script only prints the 2nd field - whether I use \t or not:

# awk -F"\t" '{ print $2 }' file
sedi6a
sedi6z

# awk '{ print $2 }' file
sedi6a
sedi6z


Rgds...Geoff
Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
Geoff Wild
Honored Contributor

Re: Quick awk question

Okay - now I see - only 1 tab....

So, basically, you want to print out the rest of the line - after the first tab...

Rgds...Geoff
Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
James R. Ferguson
Acclaimed Contributor

Re: Quick awk question

Hi Richard:

OK. I seems that you have specified a tab character as your shell's IFS.

If I do:

# IFS=
# for user in $(awk -F"\t" '{ print $2 }' input)
> do
> echo $user
> done

Using your *last* file descriptino, I get your output exactly as you descibe at commandline, but not in the script.

Regards!

...JRF...

Geoff Wild
Honored Contributor

Re: Quick awk question

Just don't do the for statement...

# cat file.awk
#!/usr/bin/sh
awk -F"\t" '{ print $2 }' input

Rgds...Geoff


Proverbs 3:5,6 Trust in the Lord with all your heart and lean not on your own understanding; in all your ways acknowledge him, and he will make all your paths straight.
OldSchool
Honored Contributor

Re: Quick awk question

The awk statement, when run at the command line is producing the correct output when the field sep is a tab, and only the first whitespace is a tab in the input file.

The "for" loop in script is parsing the input (from awk) at each whitespace.

Replace the "for" loop with something like

user=$(awk -F\t '{print $2}' input)

Hein van den Heuvel
Honored Contributor

Re: Quick awk question


Looks like a confusion between who gets to pick up the tab as seperator: the shell or awk.

You might want to make that explicit by bringing it into the awk program:


awk 'BEGIN {FS="\t"} { print $2 }' input

or

awk 'BEGIN {FS="\011"} { print $2 }' input

For next time...

1) - That 'od' output helped a lot.
2) - just attach sample input, tabs and all, as a .TXT file.

Cheers,
Hein.


OldSchool
Honored Contributor

Re: Quick awk question

....or, if the objective is to trim off the first "field" and sort, either

awk -F"\t" '{print $2}' input | sort

or

cut -f 2 input | sort

should get it.
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: Quick awk question

Well, basically you lied to us --- which is why I wanted the od output. Only the first argument is tab separated. Since it appeats that you want everything except the first argument loaded into ${user} then this should work.

awk -F "\t" '{print $2}' input | while read user
do
echo "${user}"
done

The Shell's read command will load any remianing values into the last variable. In your case, since you are reading just 1 variable, all of the remaining tokens on the input line are loaded into the single variable, user.
If it ain't broke, I can fix that.
someone_4
Honored Contributor

Re: Quick awk question

That was it Mr. Clay..

Thanks

Richard