次のような場合があります。
[email protected]
[email protected]
[email protected]
私はこれらをに変換しようとしています
[email protected]
[email protected]
[email protected]
したがって、最初の '_'(それを含む)から@(それを含まない)までのすべてを削除する必要があります。
私は何かを持っていますが、それは実際には正しく機能しません:
このスレッドに基づいて: 一度に2つの区切り文字に基づいてカット 、およびこのU&L Q&A: 区切り文字の最初の出現によって文字列を分割 。
sed 's/^.*_\([^ ]*\) .*\@\([^$]*\)$/\1 \2/' infile
しかし、運はありません。チャイムを鳴らしたい人はいますか?
複数の@
記号を使用しないと仮定すると、
sed 's/_.*@/@/' file.txt
...うまくいくはずです。
これで実際に何をしているのかわかりませんが、sed
でそのように行うことができます。
$ sed 's/\(case\).*\(@test.com\)/\1\2/' 87529.txt
[email protected]
[email protected]
[email protected]
これにより、case
と@
の間のすべてが効果的に削除されます。
awk
でも同様のことができます。
$ awk -F@ '{split($1,a,"_"); print a[1]"@"$2}' 87529.txt
Perl
(evilsoupのアプローチと同様)を使用して実行することもできます。
$ Perl -p -e 's/_.*@/@/g' 87529.txt
または、 Perl
の先読み機能 を利用できます。
$ Perl -p -e 's/_.*(?=@)//g' 87529.txt
注:Perl
の先読みと後読みを使用すると、一致する正規表現パターンに文字列を含めることができます。正規表現に対して実行される操作に含まれます。それらをキャレットの動的バージョン(^
)-行の始まり、ドル($
)-行の終わりと考えてください。これは、@
を削除した後、追加し直すよりも少しハックが少ないです。
行に複数の@
が含まれている可能性がある場合:
sed 's/^\([^@_]*\)_[^@]*@/\1@/'
または:
awk -F@ -vOFS=@ 'NF >= 2 {sub(/_.*/,"",$1)};1'
シェルがパラメータ拡張をサポートしている場合は、次のようなことができます。
while read line; do
printf "%s\n" "${line%%_*}@${line#*@}"
done < your_file_here
拡張${line%%_*}
左端を削除します_
およびその後のすべての拡張中${line#*@}
左端を削除します@
とその前のすべて。
Evilsoup'ssolution 完璧なようです!
sed
とawk
の両方を使用するさらに別のソリューション。
sed 's/_/ /g; s/@/ /g' file_name | awk '{ print $1"@"$NF '}
これは効率を正確に考慮しているわけではありませんが、おそらく正規表現をいじりたくない場合は簡単に理解できます。上記のコードは次のことを行います。
sed
の最初のパターンは、「_」を空白に置き換えます。sed
の2番目のパターンは、「@」を空白に置き換えます。したがって、ファイルの内容を複数の列に分割します。ケースtest.com
ケース1_2test.com
ケース1test.com
awk
は、分離されたコンテンツの最初と最後の列を出力するだけです。ここで、NF
はawk
の特別な記号であり、行のフィールド数を示します。ここに別のgawk
方法があります:
gawk -F_ '{if(NF>1){print $1$NF} else {print $NF}}'
_
をフィールド区切り文字として使用して、gawk
に、複数のフィールドがある場合は最初と最後のフィールドを出力し、単一のフィールドしかない場合は最後のフィールドを出力するように指示します。