2016-09-28 198 views
1

我有兩個文件,一個只包含數據,它是這樣的「CSV固定寬度」(我將這裏的簡化版本數據,原始數據中有更多的列和行):Linux shell:如何根據另一個索引從一個文件中刪除行

1 "john smith" other fields 
2 "john doe"  other fields 
3 "john black" other fields 
4 "john brown" other fields 
5 "john white" other fields 

第一列包含索引,並且字段以5個字符填充。

第二個文件就是:

2 
4 

我想獲得的是隻包含有沒有在第二個文件的索引行第3檔。所以:

1 "john smith" other fields 
3 "john black" other fields 
5 "john white" other fields 

我嘗試了不同的命令,awkgrepjointr等,但我無法得到它。

例子:

join -1 1 -2 1 file1.txt file2.txt 
awk 'NR==FNR{a[NR]=$0; next} {print a[FNR], $0}' file1.txt file2.txt 

任何幫助嗎?

+0

請在這裏張貼您的企圖! – Fazlin

+0

CSV和固定寬度是互斥的;要麼使用固定字符分隔列,要麼使用列的寬度來隱含每列之間的邊界。 – chepner

回答

3

對於file2,將其第一列存儲在數組a中。然後,如果$ 1不存在數組a中的file2,則只能打印。

awk 'NR==FNR{a[$1]=$1;next} !($1 in a){print $0}' file2 file1 
1 "john smith" other fields 
3 "john black" other fields 
5 "john white" other fields 
+1

'awk'真棒。 – VM17

+1

有一個文件存在問題:索引文件中的'n'前面有一個額外的字符'\ r'。我刪除它,現在它的作品謝謝你。 – Randomize

+0

很高興幫助:) –

2

當文件的排序中的問題,你可以使用join命令:

join -v 1 file1 file2 

說明:

默認情況下,join命令加入基於價值的行每個文件的第一列。 -v1恢復那些操作製作只是文件1的打印行,不加入一行文件2

有一件事,上面的命令預計file1和file2被排序,這意味着如果輸入文件沒有排序,它不會工作。您可以使用進程替換,以確保它們進行排序:

join -v 1 <(sort file1) <(sort file2) 

如果行的原始順序很重要,需要保留join不能使用。在這種情況下,我建議使用awk

+0

這對我不起作用,因爲原始文件會返回一些丟失的排序錯誤 – Randomize

+0

@Randomize在將文件傳遞給'join'命令之前,可以使用流程替換對文件進行排序。我已經添加了 – hek2mgl

+1

這假定您可以對文件進行排序;原來的順序可能很重要。 – chepner

0

perl溶液,類似於awk 'NR==FNR{a[$1];next} !($1 in a)' file2 file1

$ perl -lane 'if(!$#ARGV){ $h{$F[0]}=1 }else{ print if !$h{$F[0]} }' file2 file1 
1 "john smith" other fields 
3 "john black" other fields 
5 "john white" other fields 
  • -a分割輸入線上的空間,並保存到@F陣列
  • if(!$#ARGV){ $h{$F[0]}=1 }file2線的第一字段初始化散列變量作爲關鍵值
  • else{ print if !$h{$F[0]} }對於file1行,根據第一個字段打印爲已保存的散列變量中的關鍵字竹葉提取

而且,一個簡單的版本採取的事實,即file2有不同數量的領域相比,file1

$ perl -lane '$h{$F[0]}=1 if !$#F; print if !$h{$F[0]}' file2 file1 
1 "john smith" other fields 
3 "john black" other fields 
5 "john white" other fields 

這也可以用,當然awk應用:

$ awk 'NF==1{a[$1]} !($1 in a)' file2 file1 
1 "john smith" other fields 
3 "john black" other fields 
5 "john white" other fields 
0
grep -vEf "$(sed 's/\(.*\)/^\1[:blank:]/' file2)" file1 
相關問題