bashスクリプトでコマンドを実行し、最後に印刷された行数を印刷する方法は?
awkに対応するものは次のとおりです。
{ print; }
END { print NR; }
私は次のことを考えることができます。現時点ではこれは機能しますが、サブシェルの外ではインポートできません。
| (lc=0; while read; do echo $REPLY; lc=$(($lc+1)); done; echo $lc)
修正する
私の問題は全く違うようです。失敗した最初の試みは次のとおりです/dev/stdout
。
tester> { echo abc | tee /dev/stdout | wc -l; } > /tmp/abc; cat /tmp/abc
2
tee /dev/stdout
これはエラーが発生したためです。
tester> echo abc | tee /dev/stdout
tee: /dev/stdout: Permission denied
abc
これ回答ジェフ・シャーラーの作品:
tester> { echo abc | tee >(wc -l); } > /tmp/abc; cat /tmp/abc
abc
1
しかし、今朝再び試してみると効果があることがわかりました!
tmp> echo abc | tee /dev/stdout
abc
abc
ある期間の研究の終わりに、2つの問題が発見されました。
昨日失敗したときに|tee /dev/stdout
usr1としてログインし、別のusr2をsudoしましたsudo su usr2
。この場合、ソフトリンクチェーンは/dev/stdout -> /proc/self/fd/1 -> /dev/pts/1
、最後のリンクの所有者はですusr1
。だからtee
失敗しました。今日私はusr1で試してみましたが、うまくいきました。
しかし、私が気付いたもう一つのエラーtee /dev/stdout
は、すべての出力がに移動し、行数が2倍でwc -l
何も印刷されないことです。
答え1
行数をよりよく印刷する方法がわかりません。
$ seq 1 5 2>&1 | tee >(wc -l | { read lines; echo Lines of output: $lines; })
1
2
3
4
5
$ Lines of output: 5
これは、seq 1 5
コマンドの(ここで)stderrをstdoutにリダイレクトし、両方のストリームが表示されるようにします。次に、teeの入力を再コピーし、行数を計算するために実行される代替プロセスtee
に入力をコピーします。その後、出力を変数としてwc -l
読み取り、レポートを提供します。wc
$lines
答え2
使用sed
:
some_command | sed -n 'p;$='
たとえば、
$ touch file.{a..k}
$ printf '%s\n' * | sed -n 'p;$='
file.a
file.b
file.c
file.d
file.e
file.f
file.g
file.h
file.i
file.j
file.k
11
スクリプトsed
は単に入力を出力にコピーし、印刷コマンド(p
)を入力の各行に適用しますが、最後の行($
)の場合は行番号(=
)も印刷します。
答え3
単にawkコマンドを使用できます。
echo -e "foo\nbar"| awk '{印刷}END {印刷}' 金持ち バー 2