Bash玩轉指令碼3之幾個指令有趣的篩選京東評價

2021-07-12 00:10:53 字數 3550 閱讀 8875

今天在工作中遇到了乙個篩選和去重問題,饒有興致祭出mac(為了跟公司同步,寫android一直用win~),三兩個指令搞定了去重複篩選問題,回到家中意猶未盡,決定總結一下這些年使用bash做資料篩選和去重的經驗。

傳送門:

bash玩轉指令碼文章系列

那就wc -l一下看看。(wc是乙個統計的指令,「|「是管道,簡單理解就是對前面的結果繼續操作)

可以看到一共有346957行,內容還是蠻多的,我們擷取文字部分內容,可以看到內容的結構如圖所示:

基本上所有的資料的格式都是:

ok,了解了結構那現在就可以對這份資料進行我們想要的任何操作了~

這裡可以通過使用grep 指令對某個結構內一定會出現的關鍵字進行抓取,然後使用wc指令統計數量,我抓取的關鍵字是編號——」no」。

可以看到一共是有32065個評價~

1)如果格式足夠規整的話,我可以像<1>操作那樣篩選,只不過關鍵字變成了 「star 5」 ,我們可以看看結果。

注:細心的朋友可能看出了實際的指令有點點的不同,那是因為star和5間有個tab,我使用\t表示了~

2)當然,我們還有更好的方法,首先我們可以使用awk把資料進行一次格式化,然後再進行抓取和想要的操作

稍微解釋一下,我們通過grep抓取出所有的包含star的行,然後把這些行,使用\t分隔符進行分割(awk的作用)成兩列,第一列全是star,第二列則是星數,而我們把星數那一列全部print出來(這裡的head -n 30只是為了方便看,只取了頭30行)

萬萬沒想到中間竟然有一條干擾資料star186102(原來有個貨的使用者名稱包含star!):

那怎麼辦?其實很容易,使用grep -v 剔除這一條就好了~(-v表示排除再外),完整指令如下:

cat data.txt | grep "star" | awk -f "[\t]" '' | grep -v "star186102" | grep "5" | wc -l

結果和剛才的一樣~都是25274!

答案是還是使用awk,這個工具太強大了,我們對<2>中的awk指令做小小的修改:

可以看出,>,< 4.64的評分還是蠻高的!

1)首先我們要進行抓取,我選擇了抓取「心得「這個關鍵字

cat data.txt | grep "心  得"

這裡可以看到有很多很多的心得,我就不列舉了。

2)使用awk對資料進行整理

cat data.txt | grep "心  得" | awk -f "心  得\t" ''

這次分割符我使用的是」心  得\t」,注意這裡沒有中括號,因為中括號的意思是裡面的分隔符支援正規表示式,所有有沒有都行。

3)我們修改一下awk的輸出,使之列印出每一句評價的長度,然後這用sort進行排序

完整指令如下:

cat data.txt | grep "心  得" | awk -f "心  得\t" '' | sort -n -r | head -n 1

讓我們欣賞一下最佳評價:

欣賞完了,我們解釋一下,awk中的print length($2)列印出了每條心得的長度,然後加了乙個- - -作為分割,因此格式就變成了:內容長度- - -內容;然後我們使用sort進行排序,-r代表倒序,-n代表按照數字排序,這樣我們就得到了乙個從大到小的以數字開頭的列表;最後使用head -n 1取出最前的一條!

竟然「評價「的那麼認真,那麼就請出來亮個相吧!

我們通過grep語句,抓取關鍵字附近的內容來看看,這裡我們選擇的關鍵字就是「我發現作者在做班主任工作的時候也有很多的無奈「這一句話。

grep -a 5 -b 10 "我發現作者在做班主任工作的時候也有很多的無奈" data.txt

通過觀察可以看到,uaddress就是註冊時候填寫到地域資訊。雖然有部分人是沒有寫的,不過也不妨礙我們從技術到角度來實現這個問題。

我想到了用uniq,因為可以對資料進行去重,-c選項能夠列出去重後的每一項的個數~

1)首先先挑出想要的資料

grep "uaddress" data.txt | tr "\t" " "|cut -d " " -f 2

對data.txt 進行抓取uaddress關鍵字,然後使用cut指令找出需要的那一列:

需要注意的是,我擔心其中的分隔符有一些空行是空格,有一些卻是tab製表符,所以這兩個指令之間,我使用了tr指令,去把\t全部轉化為空格,接著使用cut指令的時候,則可以放心的使用空格作為分隔符了。

看來其中是有挺多的人不太喜歡填寫地域~

2)使用sort進行排序,使用uniq進行去重複統計。

完整的指令是:

grep "uaddress" data.txt | tr "\t" " "|cut -d " " -f 2 | sort | uniq -c | sort -r

我們進行了兩次sort,第一sort是把地域進行乙個排列,方便uniq的去重,第二個sort就是按照逆序從大到小排列出人數,方便我們**。

可以看到北上廣確實是主力,應該也是人多的關係,也有5925人沒有填寫,看到最後上圖找亮點~

本文遵循「署名-非商業用途-保持一致」創作公用協議

玩轉Bash指令碼 選擇結構之if

幾乎所有的程式語言中都有流程控制的概念,即順序結構 選擇結構和迴圈結構。選擇結構也稱分支結構,比如c類語言中的if和switch語句。前面我已經講過了test表示式及其簡化版 運算子的使用,這些判斷的語句即可作為if結構的條件。bash shell中我們可以使用的任何能夠有真假判斷功能的命令 無論是...

玩轉Bash指令碼 選擇結構之if

差點兒全部的程式語言中都有流程控制的概念。即順序結構 選擇結構和迴圈結構。選擇結構也稱分支結構,比方c類語言中的if和switch語句。前面我已經講過了test表示式及其簡化版 運算子的使用,這些推斷的語句就可以作為if結構的條件。bash shell中我們能夠使用的不論什麼能夠有真假推斷功能的命令...

玩轉Bash指令碼 迴圈結構之for迴圈

for 變數 in 取值列表 do 各種操作 done 還有罕見的寫法就是都寫作一行裡 for 變數 in 取值列表 do 各種操作 done 取值列表大致可以分成列舉和迭代兩類 取值列表為空格或回車符分割的字串 foriin meat sleep woman doecho i like i don...