【问题标题】:can you print a record in awk [duplicate]你能在awk中打​​印一条记录吗[重复]
【发布时间】:2024-04-29 19:15:02
【问题描述】:

可能是一个简单的问题,但我还没有找到答案。我有一个文件,其中有多个记录,由空行分隔。文件中的每个字段都由换行符分隔。我只是想打印出整个第一条记录或整个第三条记录。

awk 'BEGIN{FS="";} {print $1}' output.txt

上面打印出第一条记录每一行的第一个字母

awk 'BEGIN{FS="\n"; RS=""} {print $1}' output.txt

上面打印出第一条记录的第一个字段。

这似乎是一个很简单的问题,但我似乎无法解决它。记录具有不确定数量的字段(行)。它们只是用一个空行分隔

一个

好的,这是一个示例:

line1 record1
line2 record1
line3 record1
line4 record1

line1 record2
line2 record2
line3 record2
line4 record2
line5 record2

line1 record3

line1 record4
line2 record4

现在我想要整个第一条记录和整个第三条记录。

awk 'NR==1 || NR==3 {print $0}' output.txt
line1 record1
line3 record1

第一条记录的第一行和第三行。不好

awk 'NR==1 || NR==3' output.txt
line1 record1
line3 record1

第一条记录的第一行和第三行。不好

awk 'NR==1 || NR==3 {print $0}' output.txt
line1 record1
line3 record1

第一条记录的第一行和第三行。不好。

awk 'BEGIN{FS="\n"; RS=""} NR==1' output.txt
line1 record1
line2 record1
line3 record1
line4 record1

line1 record2
line2 record2
line3 record2
line4 record2
line5 record2

line1 record3

line1 record4
line2 record4

全部打印出来。不好

我只想要第一条和第三条记录。 第一个是:

line1 record1
line2 record1
line3 record1
line4 record1

第三个是:

line1 record3

好的,所以没有任何说明似乎对我有用,我很困惑。这是shell输出:

$ awk -v RS= -v ORS='\n\n' 'NR ~ /^(1|3)$/' output.txt
line1 record1
line2 record1
line3 record1
line4 record1

line1 record2
line2 record2
line3 record2
line4 record2
line5 record2

line1 record3

line1 record4
line2 record4

$ cat output.txt
line1 record1
line2 record1
line3 record1
line4 record1

line1 record2
line2 record2
line3 record2
line4 record2
line5 record2

line1 record3

line1 record4
line2 record4
$

我很困惑为什么这不起作用。

这是我的系统和我正在使用的 awk:

$ awk -V | head -1
GNU Awk 4.0.1
$ uname -a
Linux IEDUB2TJ5262 3.13.0-68-generic #111-Ubuntu SMP Fri Nov 6 18:17:06   UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ 

这里有什么我可能会遗漏的吗?

一个

【问题讨论】:

  • 所以要打印第一行和第三行?显示一些示例输入和所需输出以使其更清晰会很有用。
  • 我想打印一条记录,而不是行(字段)
  • 你的空行真的是空的吗?它们是否包含任何空格(空格、制表符、回车)?
  • 使用上面的例子。空白行只是空白行。进入vi
  • 为了好玩,你能检查一下cat -vet output.txt 显示的内容吗?这将有助于我们了解您的输入文件是否有一些奇怪的地方会导致 awk 误解。

标签: shell awk


【解决方案1】:

这是 THE 惯用的 awk 方式来做你想做的事,它适用于所有 awk,而不仅仅是 gawk:

$ awk -v RS= -v ORS='\n\n' 'NR ~ /^(1|3)$/' file
line1 record1
line2 record1
line3 record1
line4 record1

line1 record3

http://www.gnu.org/software/gawk/manual/gawk.html#Multiple-Line 和谷歌awk paragraph mode

如果上述方法对您不起作用,那么您的输入文件有问题(或者,您的 awk 损坏的可能性很小)。

【讨论】:

  • Ed,我在 gawk 或 FreeBSD 的 awk 的手册页中都没有看到“段落”一词。你在读什么手册页?
  • 我承认,我已经很久没有真正阅读 awk 手册页了,所以我可能记错了其中包含的内容。如果那里没有提到,那么只需谷歌awk paragparaph mode。我更新了答案下的文字,谢谢。
  • 我原谅你。 :-) 感谢您不断分享您出色的专业知识。
  • 这可能是 an answer you gave in March 的副本(也可能是其他时间)
  • 是的,我希望这个问题已被多次回答。不过,还有一些其他答案应该对 OP “有效”,所以我认为他还有其他一些尚未发现的问题,所以我们不妨从他提出的问题的正确答案开始,然后从当这对他也不起作用时。
【解决方案2】:
awk 'BEGIN{FS="\n"; RS=""} NR==1' output.txt

打印第一条记录。

【讨论】:

  • 打印所有记录
  • 如果字段和记录按照问题中的描述分开,这应该可以正常工作。如果你能提供样本输入和输出会很好。
  • 我刚刚发布了一个例子
  • 对于您提供的示例awk 'BEGIN{FS="\n"; RS=""} NR==1||NR==3' 为我获得了所需的输出。我使用 GNU awk 4.0.2
  • GNU Awk 4.0.1 但低版本不可能是问题吧?
【解决方案3】:
awk 'NR==1 || NR==3 {print $0}' output.txt

花括号之前的所有内容都称为限制。 它将确定是否将执行命令(括号内的所有内容)。 NR 表示记录数,表示输出将限制在第一条和第三条记录。

每个awk 程序只是限制命令的集合。

编辑: 其实我只是意识到{print $0}是默认动作,如果没有提供命令,这意味着:

awk 'NR==1 || NR==3' output.txt

足够了。

编辑:

在您对自己进行了更多解释之后,我建议您这样做:

awk 'BEGIN {RS='\n\n'} NR==1 || NR==3' output.txt

它将所有内容都视为记录,由两个换行符相互分隔。

【讨论】:

  • 打印出第一条记录的前两个字段
  • 好吧,你把事​​情搞得一团糟。 Record 是 Awk 语言中使用的术语,指的是 Lines,Fields 是 Awk 语言中使用的术语,指的是由 RS 分隔的记录中的元素(通常是空格)。参考我上面的编辑
  • 我知道,但在我的情况下,字段(或记录的元素)是行,记录(字段分组)由空行分隔
  • @henrikgiesel,awk 记录并不总是一行。如果您重新定义 RS 变量,您可以控制一条记录是否包含多行或什至仅包含一行的一部分。
  • 只有 GNU awk 支持超过一个字符的 RS,所以 OP 很可能没有使用 gawk,这就是为什么 RS="\n\n" 不适合他。