テキストファイルがあります。次のようになります。
www.ac.com has address 6.1.1.146 www.ac.com is an alias for ac.com. www.ac.com is an alias for ac.com.
www.ba.net is an alias for www-bn.gs.ba.com. www-bn.gs.ba.com has address 11.28.11.4 ;; connection timed out; no servers could be reached
has address
前後の列を抽出してカンマで区切りたいです。だから私は以下を取得したいと思います:
www.ac.com,6.1.1.146
www-bn.gs.ba.com,11.28.11.4
どうすればいいですか?私はこれを試しましたが、awk '{print $1,$4}' myfile > newfile
私が望むものは常に列1と4にあるわけではないのでうまくいきません。興味のある列はさまざまですが、常に区別されますhas address
。
答え1
使用grep
とsed
:
grep -o '[^ ]* has address [^ ]*' | sed 's/ has address /,/'
これは簡単だから好きです。
説明する:
grep
-o
次のパターンが見つかった各行の一致する()部分のみを出力します。
- 空白でない(
[^ ]*
)文字has address
の後に空白でない([^ ]*
)文字が続きます。
sed
has address
単に次に置き換えられます。,
答え2
存在するsed
:
sed -r 's/(.* |^)([^ ]*) has address ([^ ]*)( .*|$)/\2,\3/' myfile > newfile
説明する
sed -r 's/foo/bar/' myfile > newfile
:sed
「拡張正規表現」()と一緒に使用されるため、以下のキャプチャグループを-r
エスケープする必要はありません。()
発生項目foo
をbar
。読み書き。myfile
newfile
(.* |^)([^ ]*) has address ([^ ]*)( .*|$)
has address
:前後にスペースが1つある文字列を検索します。この前後には空白のない文字列を含める必要があり、それらをグループとしてキャプチャする必要があります([^ ]*)
。先頭の単語の前には空白(前.*
)や行の先頭(例えば)を付ける必要があります(.* |^)
。次の単語の後には、スペース(何でも.*
)または行末(たとえば)が続く必要があります( .*|$)
。\2,\3
:上記の式は行全体をキャプチャするため、2番目と3番目のキャプチャグループであるbeforeとafterの単語に置き換えられますhas address
。
答え3
perl -nE '/(\S+) has address (\S+)/ and say "$1,$2"' x
答え4
存在するawk
:
awk -v OFS=, '
{
for(i=1;i<NF;i++){
j=i+1;
if ($i=="has" && $j=="address") {
domain=i-1;
ip=i+2;
print $domain,$ip;
break;
}
}
}'
フィールドを繰り返します。 「has」が見つかり、次のフィールドが「address」の場合、そのフィールドの前後のフィールドを,
出力フィールド区切り文字として印刷します。