Awk

如何在字元串出現之前和之後提取列

  • July 31, 2018

我有一個文本文件。看起來像:

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.

使用grepsed

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

我喜歡這個,因為它很容易。


說明

grep``-o將僅輸出找到以下模式的每一行的匹配 ( ) 部分:

  • 任何非空格字元 ( [^ ]*)has address後跟任何非空格字元 ( [^ ]*)。

sed將簡單地替換has address,

sed

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

解釋

  • sed -r 's/foo/bar/' myfile > newfile:sed與“擴展正則表達式”( -r) 一起使用,因此我們不需要轉義()下面的擷取組。用 替換出現foobar。讀取myfile和寫入newfile.
  • (.* |^)([^ ]*) has address ([^ ]*)( .*|$): 查找字元串has address, 前面和後面都有一個空格。在這之前和之後應該是一個不包含空格的字元串,我們應該在一個 group 中擷取它([^ ]*)。在前導詞之前應該是一個空格(前面是任何東西,,.*)或行的開頭,即(.* |^)。後面的單詞應該是空格(後跟任何內容,.*),或行尾,即( .*|$).
  • \2,\3:上面的表達式擷取了整行,所以用第二個和第三個擷取組替換它,即單詞 before 和 after has address

引用自:https://unix.stackexchange.com/questions/459572