掃描和抓取

掃描和抓取

我有一個文件 ( *.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命令的作用可以描述如下

  1. -n除非匹配,否則不列印任何內容
  2. /rea ses/只考慮與此 RE 相符的行
  3. s!...!...!p將前兩個感嘆號 ( !) 中的 RE 替換為後面的字串,但僅在出現匹配時才列印該行
  4. RE^.*/\(.*\)\.[^.]*$匹配

    • 直到最後一個斜杠的所有內容/
    • 從那裡到最後一個點的所有內容.(記住為模式\1
    • 其他一切
  5. #4 中描述的模式的替換是用 pattern 進行的\1,即您的檔案名稱不帶尾隨點副檔名

答案4

您可以使用basename刪除尾隨副檔名:

cat a4.ses | grep -im1 'rea ses' | awk -F'[/]' '{print $NF}' | xargs basename -s .ses\' 

(為了完整性而提交,考慮到您的流程,@steeldriver 的答案更好)

相關內容