Text-Processing
cut
:選擇包含字元串的列
我有一個大文件,每行有幾列。我熟悉使用
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
會一直存在。