Text-Processing

cut:選擇包含字元串的列

  • June 30, 2016

我有一個大文件,每行有幾列。我熟悉使用cut -f -d按編號選擇特定列的方法。

我檢查了手冊,cut似乎沒有辦法正則表達式匹配列。

我具體想做的是:

  • 選擇每一行的第二列
  • 並選擇所有包含字元串“hello”的列(可能沒有,如果沒有,它可能是任何列,而不是每一行的相同列)

這個操作最方便的終端工具是什麼?

編輯:

簡化範例

x ID23 a b c hello1
x ID47 hello2 a b c
x ID49 hello3 a b hello4
x ID53 a b c d

我想要的結果是:

ID23 hello1
ID47 hello2
ID49 hello3 hello4

或者:

ID23 hello1
ID47 hello2
ID49 hello3 hello4
ID53

詳細說明給出的範例:

  • 列由一個空格定義
  • 是否“僅在字元串存在時列印”並不重要,grep如有必要,我可以只為“你好”
  • 我們可以假設字元串“hello”永遠不會出現在第 1 列或第 2 列中。

如果行尾的一個空格不會對您造成太大傷害:

$ awk '{for(i=1;i<=NF;i++) if(i==2 || $i~"hello") printf $i" ";print ""}' file

ID23 hello1 
ID47 hello2 
ID49 hello3 hello4 
ID53 

這並不假設“hello”字元串的位置。

我認為使用簡單的工具(如cut. 或者,至少,不容易。這是一個 Perl 解決方案:

$ perl -lane '$k=join " ",grep{/hello/}@F; print "$F[1] $k" if $k' file 
ID23 hello1
ID47 hello2
ID49 hello3 hello4

您可以通過grep首先使用來簡化:

$ grep hello file | perl -lane 'print "$F[1] ", join(" ", grep{/hello/}@F)'
ID23 hello1
ID47 hello2
ID49 hello3 hello4

解釋

-n選項告訴perl逐行讀取其輸入並應用-e. 該標誌為每個呼叫-l添加一個換行符 ( )。該選項將其在空白處的輸入行拆分為數組。\n``print``-a``perl``@F

因此,腳本本身正在尋找@F(所有列)匹配的所有元素hello並將它們保存為空格分隔的字元串$k( $k=join " ",grep{/hello/}@F;)。然後,如果定義了第二個欄位 ( $F[1]) 並$k列印$k,如果至少hello找到一個。

第二個版本是一樣的,只是我們不需要$k直接列印,因為我們知道至少有一個hello會一直存在。

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