sedを使用して2つの特殊文字間のすべての単語を削除するには?元の行も結果に含める必要があります。
現在のコード:
echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' | sed -r '/\W/ p; s/\W[^\W]*\W//g'
結果:
a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a123
予想される結果:
a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a b c d .123
答え1
特別な場合は、次のことができます。
- 不要なすべての文字を既知の単一文字(セットの一部)に置き換えます。
- この代替文字の 2 つのインスタンス間のすべての文字列を削除します。
echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' | sed -e '/\W/p; s/["+*#~]/#/g ; s/#[^#]\+#//g'
a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a b c d .123
を保存しようとするため、.
「単語ではない」クラスには「.」が含まれているため使用できません。どんな犠牲を払っても明示的な文字リストを提供したくない場合は、次のようにします。
- ドットを使用するのが難しい単語文字(可視、スラッシュ-O、アクセントa / e / i / o / u、またはギリシャ語/キリル文字)に置き換えます。
- [:punct:] を使用して上記の式を適用します。
- 回復ポイント。
答え2
すべての点を改行文字に変更してください。空白が保証され、句読点以外の文字が保証されます。それから、2つの句読点を貪欲なく一致させる簡単な問題です。
$ echo 'a "removeme" b +removeme+ c *removeme#d+removeme~ .123' |
sed -e 'p
y/./\n/
s/[[:punct:]][^[:punct:]]*[[:punct:]]//g
y/\n/./
'
a "removeme" b +removeme+ c *removeme#d+removeme~ .123
a b c d .123
注:これはすべてPosix sed内にあります。
答え3
Perlはこのような状況に対処するのに堪能です。ドットを含まない句読点クラスを生成するには、否定予測を使用します。
echo '......' |
perl -lpe '
print;
$p = qr/(?!\.)[[:punct:]]/;
s/$p.*?$p//g;
'