Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading from stdin OR file using awk

Tags:

bash

shell

unix

awk

So here's my code so far:

awk '{++a[length()]} END{for (i in a) print i, a[i]}' <$1 | sort -n

which reads the lengths of lines from a text file, and outputs the length of the line, and then how many lines have the same length.

So input:

hello
guys
hows
it
going

Will output:

2 1
4 2
5 2

I want it to be able to have stdin too, so i will be able to run the command "./script filename.txt" and also be able to run the command using standard input.

Is there any way this can be done with a while loop? I have tried to do something similar to:

while read line
do
    awk '{++a[length()]} END{for (i in a) print i, a[i]}' <${1:-/dev/stdin} | sort -n
done <${1:-/dev/stdin}

but nothing seems to be working correctly...

Any ideas?

like image 333
Swallows Avatar asked Dec 24 '22 18:12

Swallows


2 Answers

You may use the dash (-) as the filename, awk understands it as using stdin as the file to parse. For example:

awk '{++a[length()]} END{for (i in a) print i, a[i]}' -

Also, by not specifying a filename at all, awk also uses stdin

awk '{++a[length()]} END{for (i in a) print i, a[i]}'

And note that you can mix them both. The following will process file1.txt, stdin and file2.txt in that order:

awk '{++a[length()]} END{for (i in a) print i, a[i]}' file1.txt - file2.txt
like image 151
kontiki Avatar answered Dec 27 '22 07:12

kontiki


awk can read by default by stdin when you pipe data to awk.

You can read data from both file and stdin like this:

echo $'pipe1\npipe2\npipe3' | awk '{print NR, $0}' file -

The dash in the end represent stdin.

like image 21
George Vasiliou Avatar answered Dec 27 '22 07:12

George Vasiliou