【问题标题】:awk print to the top of the output fileawk 打印到输出文件的顶部
【发布时间】:2016-01-11 23:49:16
【问题描述】:

我有一个包含段落的输入文本文件,由 3 个空行分隔。示例:

P1
P1
empty line here
empty line here
empty line here
P2
P2
empty line here
empty line here
empty line here
P3
P3
empty line here
empty line here
empty line here

目前我正在使用将这段代码写入 *.awk 文件来获取段落:

BEGIN{ORS=RS="\n\n\n"}
/some text pattern comes here because I dont want to print every paragraph just some of them but in reversed order/

所以我希望输出文件看起来像这样:

P3
P3
empty line here
empty line here
empty line here
P2
P2
empty line here
empty line here
empty line here
P1
P1
empty line here
empty line here
empty line here

所以我想知道是否可以将每个段落打印到输出文件的顶部以获得相反的顺序。有可能吗?

【问题讨论】:

  • 你到底为什么要写“这里的空行”而不是空行???现在,如果我们想测试潜在的解决方案,我们需要删除该文本以创建示例输入和预期输出。请注意,只有 gawk 支持多字符 RS 值,POSIX awk 是免费的,它会忽略除第一个字符之外的所有字符。您可能想查看RS=""。如果您将示例输入和预期输出修复为可按原样测试,其他人可能会查看它。

标签: awk printing reverse text-processing gawk


【解决方案1】:

如果你设置了RS="",那么awk 会用空行分隔multi-line records

给定:

$ cat /tmp/so.txt
P1
P1



P2
P2



P3
P3

然后您可以获取每个记录的$0,然后反转该记录:

$ awk 'BEGIN{RS=""} {a[i++]=$0} END {while(i--){ print a[i]; print "\n\n\n"}}' /tmp/so.txt
P3
P3




P2
P2




P1
P1

如果你有一个固定的三空行分隔符(并且你有gawk),你也可以这样做:

$ awk 'BEGIN{RS="\n\n\n"} {a[i++]=$0} END {while(i--) print a[i]}' /tmp/so.txt

根据评论编辑

给定:

P1 a
P1 b

P2 a filter this block
P2 b

P3 a
P3 b

您可以添加一个模式来过滤不需要的块:

$ awk 'BEGIN{RS=""} /filter/ {next} {a[i++]=$0} END {while(i--){ print a[i]; print "\n"}}' /tmp/so.txt
P3 a
P3 b


P1 a
P1 b

【讨论】:

  • 工作得很好,速度很快,但是如果我想过滤掉段落,我必须在运行这个脚本后运行我的其他脚本(在示例中),但这是一个小问题,所以我接受了这个答案,因为它最适合我的需要。
  • 您可以将模式过滤器添加到此脚本或在管道中使用。干杯
【解决方案2】:
tac inputfile | tail -n +4 | awk '{print};END{printf("\n\n\n")}'

这个(tac)将反转输入文件的顺序,删除顶部(尾部)的空白,然后打印所有内容,但末尾有 3 个尾随换行符(因为 tac 消失了那些)。

【讨论】:

  • tac 仅在 Linux 上应注意。
  • 为了将来在 OSX 上的读者,您可以使用 tail -r filename 代替 tac
  • OS X 是否缺少 GNU coreutils?
【解决方案3】:

这对你有用吗?

cat -n inputfile | sort -r | grep -i 'pattern' | awk -F'\t' 'ORS="\n\n\n" {print $2}'

解释

cat -n inputfile           # number each line in the file
sort -r                    # sort in reverse order
grep -i 'pattern'          # grep out paragraphs with your text pattern
awk -F'\t' 'ORS="\n\n\n" {print $2}'
                           # awk out the numbers and print the second column

例如,如果您的输入文件是

Pz - The quick brown fox jumped over the lazy dog
Pz - The quick blue fox jumped over the lazy dog



Pa - The quick brown fox jumped over the lazy dog
Pa - The quick blue fox jumped over the lazy deer



Px - The quick brown fox jumped over the lazy cat
Px - The quick bronw fox jumped over the lazy dog

运行以下命令以 grep 文本模式“蓝色”的段落

cat -n inputfile | sort -r | grep -i 'blue' | awk -F'\t' 'ORS="\n\n\n" {print $2}'

会给你

Pa - The quick blue fox jumped over the lazy deer


Pz - The quick blue fox jumped over the lazy dog

【讨论】: