問題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, can I join matched content and counts withgrep 內建選項?如果沒有,怎麼辦?

問題2

我在Github上找到了一個解決方案來回答問題1:

grep -o '^[[:alpha:]_]\+[[:blank:]]*([[:blank:]]*)' /etc/rc.d/init.d/functions \
| tee >(echo -e "\n`wc -l` matched.")

但輸出往往很奇怪,是new一個之後的輸出外殼提示符為什麼?

新的 shell 提示符號後的輸出

答案1

你總是可以這樣做:

grep -o ... | awk '{print};END{if (NR) print "\n" NR " matched."}'

或完成整個事情awk(這也可以避免-o\+GNUisms):

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根據區域設定添加 a 以包含任何字母腳本中的任何字母,如grepawk(some 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不可用,可以使用單獨的 shell 來完成,並使用和bash使其提示靜音:unsetshopt

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

    若要在每行有多個符合項目時獲得完整計數 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. 透過並行進程,IE

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

    無法保證哪個進程會先完成。有時可以增加一點延遲以確保訂單。

    列印並行““首先,然後”錢幣" 延遲 1 秒後:

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

    列印並行“錢幣“首先,然後”" 延遲 1 秒後:

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

相關內容