9

Is it possible to use wc to count the chars of each line instead of the total amount of chars?

e.g.

echo -e foo\\nbar\\nbazz | grep -i ba

returns:

bar
bazz

So why doesn't echo -e foo\\nbar\\nbazz | grep ba | wc -m return a list of the lengths of those words? (3 and 4)

Suggestions?

P.S.: why are linefeeds counted with wc -m ? wc -l counts the newlines, so why should wc -m count them too?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
sclaes
  • 91
  • 1
  • 1
  • 2

3 Answers3

21

wc counts over the whole file; You can use awk to process line by line (not counting the line delimiter):

echo -e "foo\nbar\nbazz\n" | grep ba | awk '{print length}'

or as awk is mostly a superset of grep:

echo -e "foo\nbar\nbazz\n" | awk '/ba/ {print length}'

(note that some awk implementations report the number of bytes (like wc -c) as opposed to the number of characters (like wc -m) and others will count bytes that don't form part of valid characters in addition to the characters (while wc -m would ignore them in most implementations))

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
JJoao
  • 11,887
  • 1
  • 22
  • 44
1

Here's another way to do it.

for line in $(echo -e foo\\nbar\\nbazz); do echo ${#line}; done

Output:

3
3
4
MD6380
  • 111
  • 1
-1

You can iterate over the output lines and run wc for each:

echo -e foo\\nbar\\nbazz | \
grep -i ba | \
while read LINE; do echo $LINE | wc -m; done

If you don't want to count the newline characters, you can remove them:

echo -e foo\\nbar\\nbazz | \
grep -i ba | \
while read LINE; do echo ${LINE::-1} | wc -m; done

(The above assumes there is a newline after after line, so if the last line does not include a trailing newline, the count will be off.)

cherdt
  • 1,396
  • 1
  • 10
  • 21
  • This doesn't print the length of each line, it prints the length of the line, minus leading and trailing whitespace, plus the length of the next line if the first line ended with a backslash, and after replacing each whitespace-delimited word on the line by the list of matching file names if it happens to be a wildcard pattern matching that name. Approximately. See https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters for explanations. – Gilles 'SO- stop being evil' Oct 26 '17 at 20:32
  • Besides, [this kind of line-by-line processing in the shell is a bad idea](https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice/169765#169765), and using an external tool in the loop body combines the worst of both worlds. – Gilles 'SO- stop being evil' Oct 26 '17 at 20:33