自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

怎樣使用awk刪掉文件中重復的行

系統 Linux
學習怎樣使用 awk 的 !visited[$0]++ 在不重新排序或改變原排列順序的前提下刪掉重復的行。

[[285435]]

學習怎樣使用 awk 的 !visited[$0]++ 在不重新排序或改變原排列順序的前提下刪掉重復的行。

假設你有一個文本文件,你需要刪掉所有重復的行。

TL;DR

要保持原來的排列順序刪掉重復行,使用:

  1. awk '!visited[$0]++' your_file > deduplicated_file

工作原理

這個腳本維護一個關聯數組,索引(鍵)為文件中去重后的行,每個索引對應的值為該行出現的次數。對于文件的每一行,如果這行(之前)出現的次數為 0,則值加 1,并打印這行,否則值加 1,不打印這行。

我之前不熟悉 awk,我想弄清楚這么短小的一個腳本是怎么實現的。我調研了下,下面是調研心得:

  • 這個 awk “腳本” !visited[$0]++ 對輸入文件的每一行都執(zhí)行。
  • visited[] 是一個關聯數組(又名映射)類型的變量。awk 會在第一次執(zhí)行時初始化它,因此我們不需要初始化。
  • $0 變量的值是當前正在被處理的行的內容。
  • visited[$0] 通過與 $0(正在被處理的行)相等的鍵來訪問該映射中的值,即出現次數(我們在下面設置的)。
  • ! 對表示出現次數的值取反:
    • awk 中,任意非零的數或任意非空的字符串的值是 true。
    • 變量默認的初始值為空字符串,如果被轉換為數字,則為 0。
    • 也就是說:
      • 如果 visited[$0] 的值是一個比 0 大的數,取反后被解析成 false
      • 如果 visited[$0] 的值為等于 0 的數字或空字符串,取反后被解析成 true 。
    • ++ 表示變量 visited[$0] 的值加 1。
      • 如果該值為空,awk 自動把它轉換為 0(數字) 后加 1。
      • 注意:加 1 操作是在我們取到了變量的值之后執(zhí)行的。

總的來說,整個表達式的意思是:

  • true:如果表示出現次數為 0 或空字符串
  • false:如果出現的次數大于 0

awk模式或表達式和一個與之關聯的動作 組成:

  1. <模式/表達式> { <動作> }

如果匹配到了模式,就會執(zhí)行后面的動作。如果省略動作,awk 默認會打印(print)輸入。

省略動作等價于 {print $0}。

我們的腳本由一個 awk 表達式語句組成,省略了動作。因此這樣寫:

  1. awk '!visited[$0]++' your_file > deduplicated_file

等于這樣寫:

  1. awk '!visited[$0]++ { print $0 }' your_file > deduplicated_file

對于文件的每一行,如果表達式匹配到了,這行內容被打印到輸出。否則,不執(zhí)行動作,不打印任何東西。

為什么不用 uniq 命令?

uniq 命令僅能對相鄰的行去重。這是一個示例:

  1. $ cat test.txt
  2. A
  3. A
  4. A
  5. B
  6. B
  7. B
  8. A
  9. A
  10. C
  11. C
  12. C
  13. B
  14. B
  15. A
  16. $ uniq < test.txt
  17. A
  18. B
  19. A
  20. C
  21. B
  22. A

其他方法

使用 sort 命令

我們也可以用下面的 sort 命令來去除重復的行,但是原來的行順序沒有被保留。

  1. sort -u your_file > sorted_deduplicated_file

使用 cat + sort + cut

上面的方法會產出一個去重的文件,各行是基于內容進行排序的。通過管道連接命令可以解決這個問題。

  1. cat -n your_file | sort -uk2 | sort -nk1 | cut -f2-

工作原理

假設我們有下面一個文件:

  1. abc
  2. ghi
  3. abc
  4. def
  5. xyz
  6. def
  7. ghi
  8. klm

cat -n test.txt 在每行前面顯示序號:

  1. 1       abc
  2. 2       ghi
  3. 3       abc
  4. 4       def
  5. 5       xyz
  6. 6       def
  7. 7       ghi
  8. 8       klm

sort -uk2 基于第二列(k2 選項)進行排序,對于第二列相同的值只保留一次(u 選項):

  1. 1       abc
  2. 4       def
  3. 2       ghi
  4. 8       klm
  5. 5       xyz

sort -nk1 基于第一列排序(k1 選項),把列的值作為數字來處理(-n 選項):

  1. 1       abc
  2. 2       ghi
  3. 4       def
  4. 5       xyz
  5. 8       klm

最后,cut -f2- 從第二列開始打印每一行,直到最后的內容(-f2- 選項:留意 - 后綴,它表示這行后面的內容都包含在內)。

  1. abc
  2. ghi
  3. def
  4. xyz
  5. klm

參考

以上為全文。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2009-06-18 09:05:35

Unix文件管理

2010-09-01 16:47:18

SQL刪除

2019-08-28 15:43:03

sed命令Linux

2019-12-03 10:00:19

awkLinux循環(huán)

2016-08-29 20:51:16

awkLinux開源

2009-04-20 15:54:04

SQL Server重復行

2010-06-28 12:46:09

SQL Server

2016-08-10 16:07:08

awkLinux開源

2016-08-11 09:18:33

awkShellLinux

2016-10-08 20:58:50

awkLinux編寫腳本

2016-08-10 11:19:11

awkLinux開源

2025-02-26 07:53:21

2016-07-29 15:13:00

awk文本處理工具編程

2010-07-12 09:52:24

刪除 SQL Serv

2023-05-29 15:23:37

MySQL數據庫函數

2022-03-20 10:40:11

Linuxawk 腳本

2019-11-26 14:00:58

awkLinux命令

2018-03-28 17:51:24

LinuxUnix

2013-03-06 09:41:29

2020-10-15 12:30:37

Python編程語言
點贊
收藏

51CTO技術棧公眾號