假設我們現在有兩個文件 a.txt 、b.txt
a.txt 中的內容如下:
a c 1 3 d 4
b.txt 中的內容如下:
a b e 2 1 5
# Example 01
計算並集:
[root@VM_81_181_centos ~]# sort -u a.txt b.txt 1 2 3 4 5 a b c d e [root@VM_81_181_centos ~]#
# Exmaple 02
計算交集:
[root@VM_81_181_centos ~]# grep -F -f a.txt b.txt | sort | uniq 1 a [root@VM_81_181_centos ~]#
# Example 03
計算差集(a - b):
[root@VM_81_181_centos ~]# grep -F -v -f b.txt a.txt | sort | uniq 3 4 c d [root@VM_81_181_centos ~]#
# Example 04
計算差集(b - a):
[root@VM_81_181_centos ~]# grep -F -v -f a.txt b.txt | sort | uniq 2 5 b e [root@VM_81_181_centos ~]#
-----------------------------------------------------------手動分割線---------------------------------------------------------------------------
2018/09/30 更新
上面介紹了關於如何使用 grep 命令實現文件的交、差集,但是在實際操作中得到的結果卻有點問題存在
[root@VM_81_181_centos ~]# grep -F -f a.txt b.txt | sort | uniq | wc -l 4095 [root@VM_81_181_centos ~]# grep -F -f b.txt a.txt | sort | uniq | wc -l 4729 [root@VM_81_181_centos ~]#
上面的命令我是用於求 a 、b 兩個文件的交集,但是當把兩個文件的位置順序改變了一下,結果竟然是不
一樣,這是不科學的。
后來仔細想了想,grep 命令是搜索查找的命令,舉個例子:
c.txt 文件里面的內容如下:
1122 1133 1144 1155
d.txt 文件里面的內容如下:
11223344
執行 grep 命令:
[root@VM_81_181_centos ~]# grep -F -f c.txt d.txt | sort | uniq 11223344 [root@VM_81_181_centos ~]# grep -F -f d.txt c.txt | sort | uniq [root@VM_81_181_centos ~]#
根據結果,對第一條命令的解讀是:
命令執行后,在 d.txt 文件里面搜索和 c.txt 文件相匹配的字符,因為 c.txt 文件里面的字符 1122 和 d.txt 文件里面的
字符 11223344 前面的 1122 相匹配,則就把 11223344 字符作為兩個文件相同的部分記錄下來
第二條命令:
命令執行后,在 c.txt 文件里面搜索和 d.txt 文件相匹配的字符,d.txt 文件里面的 11223344 在 c.txt 文件里面找不到
與其類似或相同的字符,所以,結果為空。
現在,在 c.txt 文件里面新增字符 112233445566,結果及操作如下:
c.txt 文件內容:
1122 1133 1144 1155 1122334455
執行 grep 命令:
[root@VM_81_181_centos ~]# grep -F -f d.txt c.txt | sort | uniq 1122334455 [root@VM_81_181_centos ~]#
結論:
grep -F -f fileA fileB | sort | uniq
當 fileA 文件 在前,則表示在 fileB 文件里面搜索和 fileA 文件里面相同或者類似的字符,並將 fileB 文件里面那個字符記錄下來
同理,fileB 在前,fileA 在后的情況。
但是,在這里這並不是我們想要的結果,我們想要的結果就是我們以前學數學時候,求兩個集合的交集一樣,結果輸
出的是兩個集合共有的部分,嘗試了幾個方法,最后還是選擇使用 cat 命令。
命令格式如下:
cat fileA fileB | sort | uniq -d # 求交集 cat fileA fileB | sort | uniq -u # 求差集
這個命令比較好理解,cat 命令先把兩個文件合並成一個文件,然后在對合並后的文件進行排序、去重,-d 命令輸出文
件中相同的字符,-u 命令輸出文件中不同的字符,並且 在計算交集的時候 fileA、fileB 文件順序哪個在前在后的結果都是一樣的。
案例如下:
[root@VM_81_181_centos ~]# cat c.txt 1122 1133 1144 1155 1122334455 [root@VM_81_181_centos ~]# cat d.txt 11223344 1122 [root@VM_81_181_centos ~]#
c、d 文件內容如上
執行 cat 命令求交集:
[root@VM_81_181_centos ~]# cat c.txt d.txt | sort | uniq -d 1122 [root@VM_81_181_centos ~]# cat d.txt c.txt | sort | uniq -d 1122 [root@VM_81_181_centos ~]#
執行 cat 命令求差集:
[root@VM_81_181_centos ~]# cat c.txt d.txt | sort | uniq -u 11223344 1122334455 1133 1144 1155 [root@VM_81_181_centos ~]# cat d.txt c.txt | sort | uniq -u 11223344 1122334455 1133 1144 1155 [root@VM_81_181_centos ~]#
但是 cat 命令也有一個短板,當文件比較大的時候,就會出錯,但是在這里我們可以去借助
split 命令對文件進行分割,分而治之,然后合並,關於如何使用 split 命令,可以參考我的這篇文章
傳送門:https://www.cnblogs.com/leeyongbard/p/9594439.html
----------------------------------------------2019/04/27------------------------------------------------------------
paste命令
按列合並文件
paste 格式為:
paste -d -s -file1 file2
選項含義如下:
-d 指定不同於空格或tab鍵的分隔符,例如使用@分隔符,使用 -d @
-s 將每個文件合並成行而不是按行粘貼
- 使用標准輸入。例如:ls -l | paste 意思是只在一列上顯示輸出
例子:
#cat pas1 ID897 ID666 ID982 #cat pas2 P.Jones S.Round L.Clip
基於 paste 命令將 pas1.txt 和 pas2.txt 兩文件粘貼成兩列:
# paste pas1 pas2 ID897 P.Jones ID666 S.Round ID982 L.Clip
通過交換文件名即可指定哪一列先粘貼:
# paste pas2 pas1 P.Jones ID897 S.Round ID666 L.Clip ID982
要創建不同於空格或tab鍵的分隔符,使用 -d 選項,如下使用冒號做分隔符:
# paste -d: pas2 pas1 P.Jones:ID897 S.Round:ID666 L.Clip:ID982
要將兩列合並成兩行,需要使用 -s 選項,如下例子:
# paste -s pas1 pas2 ID897 ID666 ID982 P.Jones S.Round L.Clip
有不同意見,歡迎交流^_^