從檔案名稱中提取數字

從檔案名稱中提取數字

我有一個遵循此模型的檔案名稱:

 1.raw_bank_details_211.trg
 2.raw_bank_details_222.trg

我需要cut在unix中使用命令並剪切上面的字串以從字串中獲取211 and並回顯該值。222

我已經使用過 grep grep -o -E '[0-9]+',我需要一個替代方案。

答案1

您最好使用標準文字處理工具,而不是像cut.

以下是一些方法:


使用awk,取得_.分隔倒數第二個欄位:

awk -F '[_.]' '{print $(NF-1)}' file.txt

grep與 PCRE ( -P):

grep -Po '\d+(?=[^_]*$)' file.txt
  • -o只獲取匹配的部分

  • \d+匹配一位或多位數字

  • 零寬度正前瞻,(?=[^_]*$)確保沒有_後續直到行尾


sed

sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
  • .*_匹配最後的所有內容_

  • ([[:digit:]]+)匹配所需的數字並放入捕獲組中

  • .*與其餘的相匹配

  • 在替換中,僅\1使用捕獲的組 ,


對於perl,與以下邏輯相同sed

perl -pe 's/.*_(\d+).*/$1/' file.txt 

如果必須使用cut,請分兩步驟進行,首先取得_分隔的第四個字段,然後取得.分隔的第一個字段:

cut -d_ -f4 file.txt | cut -d. -f1

不建議這樣做,因為這需要對欄位編號進行硬編碼。


如果它是一個字串,我會使用 shell 參數擴充來完成:

% str='1.raw_bank_details_211.trg'

% str=${str##*_} 

% echo "${str%%.*}"
211

您仍然可以使用while構造並將每一行放入變數中並執行此操作,但這對於大檔案來說會很慢。另外,如果需要,您也可以使用_.asIFS並取得硬編碼欄位(如)。cut


例子:

% cat file.txt                          
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg

% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222

% grep -Po '\d+(?=[^_]*$)' file.txt         
211
222

% sed -E 's/.*_([[:digit:]]+).*/\1/' file.txt
211
222

% perl -pe 's/.*_(\d+).*/$1/' file.txt 
211
222

% cut -d_ -f4 file.txt | cut -d. -f1
211
222

答案2

cut是錯誤的工具。若要操作短字串(例如檔案名稱),請盡可能使用 shell 的字串操作工具。所有 sh 類型的 shell(sh、dash、bash、ksh、zsh 等)都有一些基本的字串操作作為變數替換的一部分。參見例如儀表板手冊在“參數擴展”下。您可以刪除與模式相符的最短/最長前綴/後綴。

您需要檔案名稱中的最後一個數字序列,因此:

  1. 透過刪除最後一位數字之前的所有內容來確定非數字後綴。
  2. 刪除該後綴。
  3. 將所有內容刪除到最後一個非數字。
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"

1除了一些 POSIX 之前的 Bourne shell,但你不關心這些。

相關內容