スキャンとgrep

スキャンとgrep

*.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つの感嘆符( )内の正規表現を!次の文字列に置き換えますが、一致した場合にのみ行を出力します。
  4. RE^.*/\(.*\)\.[^.]*$マッチ

    • 最後のスラッシュまですべて/
    • そこから最後のドットまでのすべて.(パターンとして記憶されます\1
    • ほかのすべて
  5. #4で説明したパターンの置換は\1、パターン、つまり末尾のドット付き拡張子を除いたファイル名で行われます。

答え4

basename末尾の拡張子を削除するには、次を使用できます。

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

(完全性のために提出しましたが、あなたのプロセスを考慮すると、@steeldriver の回答の方が優れています)

関連情報