質問1

質問1

質問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}'

(その場合、 は\wASCII 文字に制限されるので、または(一部の)アプローチ-Mopen=localeのように、ロケールに応じて任意のアルファベット文字の任意の文字を含めるには を追加します)grepawkawk

質問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"

一般的な回答:

  1. の単一のインスタンスでは実行できません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
    
  2. 並列プロセスでは、つまり

    tee >(echo -e "\n`wc -l` matched.")
    

    どのプロセスが最初に完了するかは保証されません。順序を保証するために、少しの遅延が追加される場合もあります。

    平行印刷 "フー" まず "ウーフ1秒遅れて:

    echo foo | tee >(sleep 1s; rev)
    

    平行印刷 "ウーフ" まず "フー1秒遅れて:

    echo foo | tee >(rev) >(sleep 1s;cat) > /dev/null
    

関連情報