説明する

説明する

テキストファイルがあります。次のようになります。

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

使用grepsed:

grep -o '[^ ]* has address [^ ]*' | sed 's/ has address /,/'

これは簡単だから好きです。


説明する:

grep-o次のパターンが見つかった各行の一致する()部分のみを出力します。

  • 空白でない([^ ]*)文字has addressの後に空白でない([^ ]*)文字が続きます。

sedhas address単に次に置き換えられます。,

答え2

存在するsed

sed -r 's/(.* |^)([^ ]*) has address ([^ ]*)( .*|$)/\2,\3/' myfile > newfile

説明する

  • sed -r 's/foo/bar/' myfile > newfilesed「拡張正規表現」()と一緒に使用されるため、以下のキャプチャグループを-rエスケープする必要はありません。()発生項目foobar。読み書き。myfilenewfile
  • (.* |^)([^ ]*) 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」の場合、そのフィールドの前後のフィールドを,出力フィールド区切り文字として印刷します。

関連情報