次のように標準入力の各行に対してコマンドを呼び出したいが、その行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
読み込み中はループが最も明確です。 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
しかし、これはただ一度に1行ずつ1行の文字数を印刷します。より読みやすいものが必要な場合は、次のいずれかが必要です。
## 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
移植性を高めるためにallの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では使用できません。