特定のパターンを除くすべてを sed -e 's///' するにはどうすればよいでしょうか?

特定のパターンを除くすべてを sed -e 's///' するにはどうすればよいでしょうか?

文字列内の % とそれに続く数字を除くすべてを sed で置換するにはどうすればよいですか? つまり、次のような文字列を除くすべてです。

%1 %1000 %55

次の形式の文字列が与えられたとします:

    1: [18x14] [history 1/2000, 268 bytes] %3
    2: [18x14] [history 1/2000, 268 bytes] %4 (active)

%3と の部品だけを取得したいのです%4が、数字は まで可能です999

答え1

$ sed 's/^.*\(%[0-9]\+\).*$/\1/' input

1 行にこれらのトークンが最大で 1 つ含まれ%123、すべての行にそのようなトークンが含まれていると仮定します。

メタ\( \)文字は一致グループをマークします。これは、\1後方参照を介して置換で参照されます。/^は行$の先頭/末尾に一致します。

それ以外の場合は、入力を事前にフィルタリングできます。例:

$ grep '%[0-9]\+' input | sed 's/^.*\(%[0-9]\+\).*$/\1/'

(すべての行にそのようなトークンが含まれていない場合)

別のバリエーション:

$ sed 's/\(%[0-9]\+\)/\n\1\n/g' | grep '%[0-9]'

(行に複数のトークンが含まれる場合)

ここでは、パイプの最初の部分で、各トークンの直前と直後に改行が挿入されています。その後、このgrep部分は%123トークン以外の行をすべて削除します。

答え2

grep -oこの場合は、次の方法を使用する方が良いでしょう:

grep -oP '\B%[0-9]{1,3}\b' inputfile

のバージョンがgrepPerl 互換の正規表現 ( -P) をサポートしていると仮定します。それ以外の場合は次のようになります。

grep -o '\B%[0-9]\{1,3\}\b' inputfile

GNU を使用するとsed、スペースを改行に変換して目的の行を取得できます。

sed 'y/ /\n/' inputfile | sed '/^%[0-9]\{1,\}/!d'

答え3

作業する際には、sedほとんどの場合、次のことをお勧めします。

/address then/s/earch/replace/

これには2つの理由があります。1つ目は、複数行のほう/addressing/が高速であるということです。探す一致を検索し、編集のために行の一部だけを選択する手間を省くため、結果をより早く絞り込むことができます。

2 番目の理由は、同じアドレスから複数の編集操作を実行できるため、作業がはるかに簡単になることです。

もちろん、この場合、あなたが示したデータだけを考えると、実質的な違いはありません。それでも、あなたが尋ねていることを私が行う方法は次のようになります。

sed '/^[^%]*\|[^0-9]*$/s///g' <<\DATA
    1: [18x14] [history 1/2000, 268 bytes] %3
    2: [18x14] [history 1/2000, 268 bytes] %4 (active)
DATA

#OUTPUT
%3
%4

全ての文字を選択するだけです非%行の先頭の文字とすべての非数値アドレスの行末から文字を削除し、s///- で削除します。これで完了です。

現在の形式では、行を入力すると予期しない方法でデータが破損する可能性があります。ないコンボを含むので%digit、アドレス指定が重要になります。少し変更すると、次のようになります。

/%[0-9]/s/[^%]*\|[^0-9]*$//g

より安全になるそしてもっと早く。

答え4

私の解決策では、sed ではなく、拡張正規表現と一致のみのオプションを使用した grep を使用します。


$ cat file
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
$ cat file | grep -Eo '%[0-9]+'
%3
%4

この場合、 sed を使用するよりも grep を使用する方が簡単です。

関連情報