我正在尝试编辑包含多个重复项的文本文件。目标是仅保留字符串的第一个匹配项并删除同一字符串的其余重复行。
在示例文件中
* 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
不加区别地删除所有重复项。
我尝试使用这些解决方案的变体以及 GNU 的sed
循环格式,例如
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 等,只需告诉我函数/库名称是什么,我就会在那里搜索它。
谢谢。
答案1
您可以简单地修改 awk!a[$0]++
范例以使递增模式依赖于:
awk '!a[$0]; /^\* Title/{a[$0]++}' file
答案2
在 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