【问题标题】:awk: multiline sort and delete not working as expected with RSawk:多行排序和删除无法按预期与 RS 一起工作
【发布时间】:2020-06-10 01:51:32
【问题描述】:

我正在努力处理具有RS of \n (\012)\035 FS 的多行文件。

我的最终目标是根据某一列删除重复但文件不是固定宽度的,有些列是可选的。

我尝试使用以下命令解析文件:

awk -v FS='\035' -v RS= -v ORS='\n' '{print $4}' filename

awk 'BEGIN{RS="\n"; FS="\035"} {print NR, NF, $0}' filename

awk -v RS='\012' -F'\035' '!seen[$4]++' filename

不幸的是,如果一条记录跨越多行,awk 不会将这些行视为记录的一部分:

1 "Column4"
2 "Column4"
3
4 "Column4"
5
6 "Column4"
7
8
9
10 "Column4"

在上述文件中,空行代表记录的一部分,因此第 4 行实际上应该是第 3 行(第 3 行中不存在 Column4,因为它是第 2 行的多行记录)。当我在 vi 编辑器中查看文件时,跨越的记录以 ^M$ 结尾,而记录的结尾仅以 $ 结尾。

我希望有人可以指导我如何正确读取此文件,以便我最终可以删除基于重复 Column4 值的记录。

awk -v RS='\012' -F'\035' '!seen[$4]++' filename

以上仅适用于单行记录,但我需要帮助删除基于 Column4 的重复行,无论是单行还是多行,但应考虑 RS 和 FS。

添加样本输入:

"TEST"^]"1234"^]"ABCD"^]"121212"^]"1"^]"Some^M$
test data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"DEFG"^]"121212"^]"1"^]"Some test data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"HIJK"^]"232323"^]"1"^]"Some test ^M$
data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"LMNO"^]"232323"^]"1"^]"Some ^M$
test ^M$
data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"PQRS"^]"343434"^]"1"^]"Some test data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"121212"^]"343434"^]"1"^]"Some ^M$
Test^M$
^M$
data"^]"0"^]"08.06.2020"^]$
"TEST"^]"1234"^]"TUVW"^]"565656"^]"1"^]"Some^M$
test^M$
data"^]"0"^]"08.06.2020"^]$

输出应该只打印唯一的第 4 列值:

121212
232323
343434
565656

【问题讨论】:

  • 请在您的问题中添加示例输入(无描述、无图像、无链接)以及该示例输入所需的输出(无评论)。
  • 你怎么知道它是否是真正的换行符?也用于删除控制 M ^M 字符尝试 dos2unix
  • @Digvijay S 如果我删除 Control M 字符,则不会指示记录是多行记录还是单行记录。
  • 试试tr '\n' ' ' | tr '\r' '\n'
  • 您的问题中命令太多,混乱太多,并且没有示例输入。创建一个小而有代表性的样本输入文件。在其上运行cat -Ev file 以分别以^M$ 字符显示CR 和LF 的位置。将其复制/粘贴到您的问题中作为示例输入,并添加给定输入的预期输出以及您认为应该产生该输出的命令及其实际输出的内容。鉴于我们绝对可以帮助您。

标签: awk


【解决方案1】:

相信你感兴趣的是以下几点:

awk 'BEGIN{FS="\035"}
     (record && $0 ~ "\035$") { split(record,a); if (!s[a[4]]++) print record; record="" }
     { record = record (record?"ORS":"") $0 }
     END { split(record,a); if (!s[a[4]]++) print record; }' file

或使用 GNU awk 处理多字符 RS:

awk 'BEGIN{FS="\035";RS="\035\012"}!s[$4]++' file

【讨论】:

  • 你为什么用 6 美元?我尝试用 $4 替换它并且没有输出。使用您的命令会产生不正确的结果。
  • 对不起,应该是 4 美元
  • 最终将其用于:awk 'BEGIN{FS="\035";RS="\035\012"} !s[$4]++' 文件名,谢谢
猜你喜欢
  • 2019-09-04
  • 1970-01-01
  • 2012-02-19
  • 2019-12-14
  • 1970-01-01
  • 2021-11-10
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多