Reading from stdin OR file using awk

2019-02-27 02:09发布

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?

2条回答
不美不萌又怎样
2楼-- · 2019-02-27 02:50

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
查看更多
混吃等死
3楼-- · 2019-02-27 03:00

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.

查看更多
登录 后发表回答