linux重復行
A. 【shell】linux刪除文本重復行
通常如果我們想獲取一個文件里不重復的行的時候,我們可以直接通過 sort -u 命令,先把文件排序,然後去掉連續的重復行就行。
可是,如果我們去掉重復行之後,還想保留文件原有的順序,該怎麼辦呢?
雖然 Linux 下有個看上去似乎很有用的命令叫uniq,但事實上 uniq 命令僅僅只對連續的重復行有效。
如果不排序,直接使用 uniq 命令是沒有用的;使用 sort -u 的話,我們就丟失了文件原有的行的順序了。
一個終極的解決方案是使用 awk:
簡要解釋一下:awk 的基本執行流程是,對文件的每一行,做一個指定的邏輯判斷,如果邏輯判斷成立,則執行指定的命令;如果邏輯判斷不成立,則直接跳過這一行。
我們這里寫的 awk 命令是!x[$0]++,意思是,首先創建一個 map 叫x,然後用當前行的全文$0作為 map 的 key,到 map 中查找相應的 value,如果沒找到,則整個表達式的值為真,可以執行之後的語句;如果找到了,則表達式的值為假,跳過這一行。
由於表達式之後有++,因此如果某個 key 找不到對應的 value,該++操作會先把對應的 value 設成 0,然後再自增成 1,這樣下次再遇到重復的行的時候,對應的 key 就能找到一個非 0 的 value 了。
我們前面說過,awk 的流程是先判斷表達式,表達式為真的時候就執行語句,可是我們前面寫的這個 awk 命令里只有表達式,沒有語句,那我們執行什麼呢?原來,當語句被省略的時候,awk 就執行默認的語句,即列印整個完整的當前行。就這樣,我們通過這個非常簡短的 awk 命令實現了去除重復行並保留原有文件順序的功能。
B. Linux刪除文件內重復行
第一,用sort+uniq,注意,單純uniq是不行的。
第二,用sort+awk命令,注意,單純awk同樣不行,原因同上。
第三,用sort+sed命令,同樣需要sort命令先排序。
以上原理都是上下行比對,如果中間開了幾行,uniq就不生效
例如:
111
222
111
是不能正確排序的,必須是:
111
111
222
uniq才會生效,所以都需要先用sort 來排序,然後將結果輸出到其他文件。
C. linux:排序,唯一與重復
對一組文件進行排序
按照數字順序進行排序
逆序排序
按照月份排序
合並兩個已經排序過的文件
找出已排序文件中不重復的行
檢查文件是否已經排序過
按照某一列進行排序:-k
按照特定范圍內的一組字元進行排序
列印唯一行
只顯示唯一的行
統計各行在文件中出現的次數
找出文件中重復的行
==========================================================================================================
D. LINUX下去除文件中重復的行
wk肯定行
這是一個cu的精華帖,差不多,對於你的問題你給稍等我修改一下。(ps感謝紅袖添香大姐)
CU精華 經典回顧
#假設我有如下文件:
#cat aa
#123 def1 456
#345 def2 812
#123 def3 563
#322 def4 684
#123 def5 879
#......................
#現在我想把第一列中欄位相同的合並,第一列不相同的則保留,合並的原則就是保留第一個出現的前兩個欄位,第三個欄位則把結果相加,以上面的示例為例:
#
#就是對於123開頭的需要合並,合並後應該成為如下:
#cat aa
#123 def1 1898
#345 def2 812
#322 def4 684
#請問用shell如何實現?
#希望各位幫助!,謝謝!!
#要求總結:
#1 合並相同的第一列數據,並且計算第三列和
#2 第二列只保留第一次出現
#3 第一列順序不變
覺得這個問題很經典,所以從CU論壇轉過來了。
請大家一起學習
我們站在巨人的肩膀上。
問題補充:
看不太懂實現可以講一下思路嗎?
a[$1]+=$3
if(length(b[$1])==0)b[$1]=$2
我是這樣做的
--------------------------2
謝謝你的補充, 已經明白了你對split的適用技巧,是用split(a[$1],tmp)在碰到匹配的$1時取出以前的統計結然後再用$3加上以前的結果是吧,很巧妙。謝謝
但是有2個問題:
1不滿足 第二列保留第一次出現記錄(現在是保留最後一次出現)
2不滿足 第一列按照原來文件順序出現
看看這個
awk 'BEING
{
a[$1]+=$3
if(length(b[$1])==0)b[$1]=$2
if($1 in ind)next
ind[$1]
key[n]=$1
n++
}
END{
for(i in key)print key[i],b[key[i]],a[key[i]]
}' filename
#######################
#######################
#######################
這樣就行了
#!/bin/bash
awk 'BEGIN
{
if($0 in a)next
a[$0]
b[n]=$0
n++
}
END{
for(i in b)print b[i]
}' data
前提是你的數據文件裡面每行沒有空格,如果有用-F設定一個沒有的字元作分隔符就
E. 如何快速刪除Linux文件中的重復數據行
用uniq,如下,將 1.txt 中 所有 "相鄰" 重復行合並成一行,結果存入 2.txt
uniq1.txt>2.txt
如果是想將相鄰重復行徹底刪掉(而不是合並成一行),可以用
uniq-u1.txt>2.txt
F. 如何快速刪除Linux文件中的重復數據行
用uniq,如下,將 1.txt 中 所有 "相鄰" 重復行合並成一行,結果存入 2.txt
1
uniq 1.txt > 2.txt
如果是想將相鄰重復行徹底刪掉(而不是合並成一行),可以用
1
uniq -u 1.txt > 2.txt