
我有一個遵循此模型的檔案名稱:
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 等)都有一些基本的字串操作作為變數替換的一部分。參見例如儀表板手冊在“參數擴展”下。您可以刪除與模式相符的最短/最長前綴/後綴。
您需要檔案名稱中的最後一個數字序列,因此:
- 透過刪除最後一位數字之前的所有內容來確定非數字後綴。
- 刪除該後綴。
- 將所有內容刪除到最後一個非數字。
filename=1.raw_bank_details_211.trg
suffix="${filename##*[0-9]}"
number="${filename%"$suffix"}"
number="${number##*[!-0-9]}"
1除了一些 POSIX 之前的 Bourne shell,但你不關心這些。