スキャンとクロール

スキャンとクロール

*.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文字まで印刷して、末尾の5文字を​​削除する操作をawkにハードコードするだけです。

awk -F/ '{print substr($NF, 1, length($NF)-5)}'

拡張子の長さが異なる場合は、印刷する前に空の文字列に置き換えてください。

awk -F/ '{gsub(/\..+$/, "", $NF); print $NF}'

答え2

grepPerl互換正規表現(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最初の2つの感嘆符(!)のREを次の文字列に置き換えます。ただし、一致する場合にのみその行を印刷してください。
  4. RE^.*/\(.*\)\.[^.]*$マッチ

    • 最後のスラッシュまでのすべて/
    • そこから最後の地点までのすべて.(パターンとして記憶される\1
    • 他のすべて
  5. #4に記載されているパターンの交換はパターンで行われます\1。つまり、後にドット拡張子がないファイル名です。

答え4

basename以下を使用して末尾の拡張子を削除できます。

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

(完全性のために提出され、@steeldriverの答えはプロセスを考慮する方が良いです)

関連情報