Grep 3 將大寫字母和數字轉換為兩個變數

Grep 3 將大寫字母和數字轉換為兩個變數

我建立了一個腳本,它使用循環for loop遍歷 IBM 腳本來取得目錄的大小。然後,該腳本將目錄大小和路徑輸出到 Slack 通道,以便於查看。該程式可以運行,但 IBM 腳本的輸出很大,需要格式化才能在 Slack 中輕鬆閱讀。因此,我需要收集兩個訊息,這些訊息將透過管道傳輸到兩個單獨的變數中,這些變數用於創建 Slack 訊息。我的腳本如下圖所示:

SIZE () {
  for dir in /path/to/dir/*
  do
    cd /usr/lpp/mmfs/samples/ilm/
    SLACKMESSAGE=$(./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h)
    SLACK
  done
}

/path/to/dir/*父目錄也是如此,IBM 腳本./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h 將循環遍歷所有子目錄(一層深)並取得它們的大小。輸出看起來像:

[I] 2018-05-31@16:32:55.798 Policy execution. 0 files dispatched.
[I] 2018-05-31@16:32:55.804 Policy execution. 0 files dispatched.
File system scan complete.
534.5M     total
mmapplypolicy du for /path/to/directory/SPI/ complete at Thu May 31 17:32:55 2018

這不是最乾淨的輸出,因此我想將上面範例中的目錄大小透過管道傳輸534.5M到名為 的變數中SIZE,並將 傳輸SPI到另一個名為 的變數中PROJECT。當然,作為一個循環,SIZEPROJECT變數將在上面範例中的每個目錄上發生變化/path/to/dir/。在我上面的函數中調用的 Slack 函數將使用這兩個變數。我正在努力弄清楚如何將這兩個變數放入變數中。有人有解決辦法嗎?謝謝!

答案1

一次完成:

eval "$(yourscript | awk -v q=\' '
  $1 ~ /^[[:digit:]]+(\.[[:digit:]]+)?[MGT]$/ {
    print "SIZE=" $1
  }
  match($0, /[[:upper:]]{3}/) {
    print "PROJECT="q substr($0, RSTART, RLENGTH) q
  }')"

請注意,某些awk實作(如nawk或 Solaris)mawk或較早版本的gawk不支援{x,y}/{x}正則表達式間隔運算子(對於較舊(而非古老)版本的,您可以在支援它們的環境中gawk運行它為.POSIXLY_CORRECT=anything[[:upper:]]{3}[[:upper:]][[:upper:]][[:upper:]]

答案2

我非常懷疑這就是您所需要的,但這逐字回答了您當前的問題。

第一部分(假設 GNUgrep或相容):

project="$(yourscript|grep -oE '[[:upper:]]{3}')"

第二部分:

size="$(yourscript|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"

組合起來,運行腳本一次、保存輸出和 grep 並在保存的輸出上分配會更簡單:

output="$(script)"
size="$(printf '%s\n' "$output"|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
project="$(printf '%s\n' "$output"|grep -oE '[[:upper:]]{3}')"

一些解釋
grep -o- 只返回 grep 的對象,而不是整行
-E- 擴展正則表達式
[[:upper:]]- 僅匹配大寫字母([AZ],但不考慮區域設置)
{3}- 將匹配限制為恰好 3 個連續字符。
[[:digit:]]- 匹配數字([0-9],同樣不考慮區域設定)
+- 匹配 1 次或多次
\.- 匹配一個點
(...)?- 匹配 0 或 1 次 - 這確保沒有小數點的數字也可能被捕獲
[xy]- 精確匹配一個項目x或y。

相關內容