我想为标准输入的每一行调用一个命令,很像xargs
,但该行应该作为标准输入传递,而不是作为命令行参数传递:
cat some-file.txt | <magic> | wc -c
- 这应该打印文件每行中的字符数。
我有什么选择?
答案1
一个简单的循环怎么样
while IFS= read -r line ;
do
printf "%s" "$line" | wc -c
done < some-file.txt
答案2
while-read 循环是最清晰的。如果你想使用 xargs 为每一行做一些事情,你可能会得到像这样的怪物:
printf "%s\n" "foo bar" one " 1 2 3" |
xargs -d '\n' -n 1 -I LINE bash -c 'wc -c <<< "LINE"'
8
4
7
相当昂贵,因为你必须为每一行生成一个 bash 进程。
答案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
然而,这将只是打印一行上的字符数,一次一行。如果您想要更具可读性的内容,您可能需要以下之一:
## 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
为了获得更大的便携性,您可以使用printf '%s' "$i"
而不是所有echo -n
的
答案4
Z壳
使用选项可以避免将行存储到变量中-e
setopt pipefail
cat some-file.txt |
while read -re | wc -c
do
done
-r
\
按原样读取s
-e
回显输入而不是将其分配给任何变量
pipefail
一旦这样做,就会read -re | wc -c
以非零状态代码退出read -re
,它将出现在文件末尾
不幸的是,这个选项在 Bash 中不可用