
我有一個文件 ( *.ses
),其中包含以下行
$ rea ses '../../../../abcdefgh/abcd_efgh-A20_ABC-abcdefgh-Abcdefgh_Abcdef_123er_vb001.ses'
當我使用這個命令時:
cat a4.ses | grep -im1 'rea ses' | awk -F'[/]' '{print $NF}'
輸出是:
abcd_efgh-A20_ABC-abcdefgh-Abcdefgh_Abcdef_123er_vb001.ses'
我只想輸出為:
abcd_efgh-A20_ABC-abcdefgh-Abcdefgh_Abcdef_123er_vb001
沒有擴展名。
我怎樣才能做到這一點?
答案1
如果.ses'
是靜態擴展,只需將刪除尾隨 5 個字元的操作硬編碼到 awk 中,方法是從開頭列印字串到末尾 5 個字元:
awk -F/ '{print substr($NF, 1, length($NF)-5)}'
如果擴展名的長度可能不同,則在列印之前將其替換為空字串:
awk -F/ '{gsub(/\..+$/, "", $NF); print $NF}'
答案2
如果您grep
支援 perl 相容的正規表示式 (PCRE) 語法:
$ grep -Po 'rea ses.*/\K[^.]*' file
abcd_efgh-A20_ABC-abcdefgh-Abcdefgh_Abcdef_123er_vb001
解釋:
- 匹配
rea ses
然後貪婪地一切直到/
包容;然後 - 匹配最長的非句點字元序列
- 丟棄 (
\K
) 左側部分並僅輸出匹配 (-o
)的剩餘部分
答案3
您可以放棄該管道並sed
使用
sed -n '/rea ses/s!^.*/\(.*\)\.[^.]*$!\1!p' a4.ses
輸出
abcd_efgh-A20_ABC-abcdefgh-Abcdefgh_Abcdef_123er_vb001
該sed
命令的作用可以描述如下
-n
除非匹配,否則不列印任何內容/rea ses/
只考慮與此 RE 相符的行s!...!...!p
將前兩個感嘆號 (!
) 中的 RE 替換為後面的字串,但僅在出現匹配時才列印該行RE
^.*/\(.*\)\.[^.]*$
匹配- 直到最後一個斜杠的所有內容
/
- 從那裡到最後一個點的所有內容
.
(記住為模式\1
) - 其他一切
- 直到最後一個斜杠的所有內容
#4 中描述的模式的替換是用 pattern 進行的
\1
,即您的檔案名稱不帶尾隨點副檔名
答案4
您可以使用basename
刪除尾隨副檔名:
cat a4.ses | grep -im1 'rea ses' | awk -F'[/]' '{print $NF}' | xargs basename -s .ses\'
(為了完整性而提交,考慮到您的流程,@steeldriver 的答案更好)