
質問1
使うことができます
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions
以下のような出力が得られます。
systemctl_redirect ()
checkpid()
__kill_pids_term_kill_checkpids()
__kill_pids_term_kill()
__pids_var_run()
__pids_pidof()
daemon()
killproc()
pidfileofproc()
pidofproc()
status()
echo_success()
echo_failure()
echo_passed()
echo_warning()
update_boot_stage()
success()
failure()
passed()
warning()
action()
strstr()
is_ignored_file()
is_true()
is_false()
apply_sysctl()
また、一致した出現回数も知りたいので、-c
オプションを使用します。今回は のみを取得します26
。一致した内容とカウントを組み合わせることはできますか?grep
内蔵オプションはありますか? そうでない場合は、どうすればいいですか?
質問2
質問 1 の答えとなる解決策を Github で見つけました。
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions \
| tee >(echo -e "\n`wc -l` matched.")
しかし、出力は奇妙なものになることが多く、新しいシェルプロンプト!なぜ?
答え1
いつでも次のことができます:
grep -o ... | awk '{print};END{if (NR) print "\n" NR " matched."}'
または、全体を で実行しますawk
(これにより、-o
および\+
GNU 主義も回避されます)。
awk 'match($0, /^[[:alpha:]_]+[[:blank:]]*\([[:blank:]]*\)/) {
print substr($0, RSTART, RLENGTH)
n++
}
END{if (n) print "\n" n " matched.")'
またはperl
:
perl -lne 'for (/^\w+\h*\(\h*\)/g) {print; $n++}
END {print "\n$n matched." if $n}'
(その場合、 は\w
ASCII 文字に制限されるので、または(一部の)アプローチ-Mopen=locale
のように、ロケールに応じて任意のアルファベット文字の任意の文字を含めるには を追加します)grep
awk
awk
質問2については、bash
(とは逆にzsh
)プロセス置換で開始されたコマンドを待たないため、このような問題が発生します。プロセス置換出力が順序どおりではありません詳細については。
答え2
tee
のようなツールを使う代わりにpee
:
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions |
pee cat 'sleep 1; echo -e "\n`wc -l` matched."'
pee
が利用できない場合は、別のbash
シェルを使用して、unset
およびを使用してプロンプトを黙らせることができますshopt
。
bash -c \
"unset PS0 PS1 PS2 PS3
shopt -u promptvars
grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' \
/etc/rc.d/init.d/functions |
tee >( sleep 1s; printf '\n%s matched.' `wc -l`; )
sleep 2s"
一般的な回答:
の単一のインスタンスでは実行できません
grep
。1 行に複数の一致がある場合に完全なカウントを取得するには
grep -o
、 を使用しますwc -l
。printf "foo bar baz\nbuz biz\n" | grep -o 'b[^ ]*' | wc -l
出力:
4
プレフィックス付きのカウントが必要な場合は、、
nl
(またはcat -n
)を使用します。printf "foo bar baz\nbuz biz\n" | grep -o 'b[^ ]*' | nl
出力:
1 bar 2 baz 3 buz 4 biz
並列プロセスでは、つまり
tee >(echo -e "\n`wc -l` matched.")
どのプロセスが最初に完了するかは保証されません。順序を保証するために、少しの遅延が追加される場合もあります。
平行印刷 "フー" まず "ウーフ1秒遅れて:
echo foo | tee >(sleep 1s; rev)
平行印刷 "ウーフ" まず "フー1秒遅れて:
echo foo | tee >(rev) >(sleep 1s;cat) > /dev/null