Bash

字元串中路徑、製表符和空格後面的 Grep 編號

  • March 23, 2021

給定一個字元串 s

s="B /home/BL/004_010_0100.0      23      0.031"

如何僅 grep 字元串中路徑、製表符和空格後面的數字?

在上面的字元串 s 中,我想提取數字 23。

num=$(echo $s | grep 'B .*\t (\d*)')

將字元串視為一組以空格分隔的欄位,您需要倒數第二個欄位:

num=$( awk '{ print $(NF-1) }' <<<"$s" )

或者,在沒有此處字元串的貝殼中,

num=$( printf '%s\n' "$s" | awk '{ print $(NF-1) }' )

這會將字元串輸入$sawk命令中。該awk命令輸出倒數第二個以空格分隔的欄位。此結果分配給num變數。

測試:

$ s="B /home/BL/004_010_0100.0      23      0.031"
$ num=$( awk '{ print $(NF-1) }' <<<"$s" )
$ printf 'num is "%s"\n' "$num"
num is "23"

如果您的數據$s來自命令,那麼您可以awk直接將其輸入,而不是將其儲存在中間變數中:

num=$( some-command | awk '{ print $(NF-1) }' )

grep是一個返回匹配的工具(忽略該工具的某些實現中可用的非標準-o選項)。如果我們首先根據字元串中的空格將字元串轉換為多行,我們可以使用它grep來挑選數字$s

$ tr -s '[:blank:]' '[\n*]' <<<"$s" | grep -x '[[:digit:]]\{1,\}'
23

此處使用的tr命令將字元串從

B /home/BL/004_010_0100.0      23      0.031

進入

B
/home/BL/004_010_0100.0
23
0.031

並且該grep命令挑選出由數字組成的行(該-x選項將強制給定模式匹配完整的行)。這顯然只有在您要查找的數字是正整數時才有效。

如果您知道您會對倒數第二個“欄位”感興趣,那麼您可以使用tailandhead代替:

$ tr -s '[:blank:]' '[\n*]' <<<"$s" | tail -n 2 | head -n 1
23

…或sed

$ tr -s '[:blank:]' '[\n*]' <<<"$s" | sed -n -e '${ g; p; }' -e h
23

上述所有變體都是標準且可移植的。cut如果我們使用非標準rev實用程序將行反轉兩次,我們也可以使用提取倒數第二個欄位:

$ rev <<<"$s" | tr -s '[:blank:]' '[\t*]' | cut -f 2 | rev
23

在這裡,我們還使用tr製表符替換所有空白字元(並將它們壓縮到單個製表符中)。 然後在再次反轉提取的數據cut之前簡單地提取第二個欄位。rev

你可以用 Perl 試試:

echo "$s" | perl -e 'for(<>){/B\s+.*?\s+(\d+)\s+/;print $1}'

在這裡,我們找到了字元串:

  • B特點
  • 後跟一個或多個空格字元 -\s+
  • 後跟第一個空格字元之前的所有惰性字元 -.*?\s+
  • 後面是我們想要的數字 - 在括號中的擷取組中擷取它(\d+)- 它保存在$1特殊變數中
  • 後跟一個或多個空格字元 - \s+

這個正則表達式可以被細化(例如用^$操作符來指出字元串的開始和結束)。

閱讀更多關於正則表達式的資訊。

引用自:https://unix.stackexchange.com/questions/640661