Linux
刪除特定行的重複項,僅保留每個行的第一次出現而不觸及其他未指定的重複項
我正在嘗試編輯包含多個重複項的文本文件。目標是僅保留字元串的第一個匹配項,並刪除同一字元串的其餘重複行。
在範例文件中
* Title 1 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src * Title 1 ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src * Title 2 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src * Title 2 ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src
我想保留其中一個,
* Title N
並在文件中保留所有其他不相關/未指定的重複行。所以結果是:* Title 1 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src * Title 2 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src
刪除重複項的傳統解決方案,例如
uniq file.txt
awk '!a[$0]++' contents.txt
shell - 如何刪除文件中的重複行而不在Unix中對其進行排序 - Thinbug
perl -ne 'print if ! $x{$_}++' file
不加選擇地刪除每個重複項。
我嘗試使用這些解決方案的變體以及
sed
循環格式的 GNU,例如duplicateLines=$(grep -E "^\* .*" file.org | uniq) printf '%s\n' "$duplicateLines" | while read -r line; do sed "s/$line//g2" file.org done
沒有成功。我不介意絕對性能,因此進行多次迭代(例如
sed
在循環內呼叫以一次刪除一個指定字元串)是沒有問題的。任何見解將不勝感激。
能夠在 shell 腳本中執行此操作會很好,但我對 Python、C、Java 等替代解決方案持開放態度,只需告訴我函式/庫名稱是什麼,我正在那裡搜尋.
謝謝。
您可以簡單地修改 awk
!a[$0]++
範式以使遞增模式依賴:awk '!a[$0]; /^\* Title/{a[$0]++}' file
在 awk 中,我們習慣性地使用一個名為的數組
seen[]
來區分字元串的第一次和後續出現,例如:awk '!seen[$0]++'
只會輸出每行的第一次出現。
在您的情況下,您只想在目前行開頭時使用它,
* Title
這樣就可以了:$ awk '!( /^\* Title/ && seen[$0]++ )' file * Title 1 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src * Title 2 ** Subtitle 01 #+begin_src Line 001 Line 002 #+end_src ** Subtitle 02 #+begin_src Line 001 Line 002 #+end_src