4

I want to invoke a command for every line of the standard input, much like xargs, but the line should be passed as standard input, not as a command-line argument:

cat some-file.txt | <magic> | wc -c
  • this should print the number of characters in each line of the file.

What are my options?

(The actual use case is processing a tail -f/grep combination with jq which seems to only start processing when it reaches EOF.)

7

How about a plain loop

while IFS= read -r line ;
do
   printf "%s" "$line" | wc -c
done < some-file.txt
4

A while-read loop is the most clear. If you want to use xargs to do something for each line, you may end up with a monstrosity like this:

printf "%s\n" "foo bar" one " 1 2 3" | 
xargs -d '\n' -n 1 -I LINE bash -c 'wc -c <<< "LINE"'
8
4
7

Pretty expensive since you have to spawn a bash process for each line.

3
cat file.txt | while IFS= read -r i; do echo -n "$i" | wc -c; done
##  or (better):
while IFS= read -r i; do echo -n "$i" | wc -c; done < file.txt

However, this will just print the number of characters on a line, one line at a time. If you want something more readable, you might want one of the following:

##  Prints the contents of each line underneath the character count:
while IFS= read -r i; do echo -n "$i" | wc -c; echo "$i"; done < file.txt
##  Prints the line number alongside the character count:
n=0; while IFS= read -r i; do n=$((n+1)); echo -n "line number $n : "; echo -n "$i" | wc -c; done < file.txt

For greater portability you could use printf '%s' "$i" instead of all the echo -ns

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.