【问题标题】:awk - print data before RS, same lineawk - 在 RS 之前打印数据,同一行
【发布时间】:2013-12-24 00:04:43
【问题描述】:

我有一个输出到 awk,并在某些行的末尾找到了一个好的 RS 字符串。 但是当我将尾随字符串定义为 RS 时,awk 只会删除整行内容。我希望保留 RS 字符串之前的数据,并且只从行中删除 RS。

awk 的输入示例:

data data data RS_STRING
data SEARCHED_STRING data data
data data

data data data RS_STRING
data data data
data data

data data data RS_STRING
data SEARCHED_STRING data data
data data

来自 awk 的期望输出:

data data data
data SEARCHED_STRING data data
data data

data data data
data SEARCHED_STRING data data
data data

我目前的 awk 语法是:

awk '/SEARCHED_STRING/' RS = "RS_STRING"

...我得到:

data SEARCHED_STRING data data
data data


data SEARCHED_STRING data data
data data 

正如您通过将 RS_STRING 定义为 RS 所看到的,awk 会删除 RS 之前的所有数据,包含在该行中。

过去三天我一直在寻找解决方案,但还没有找到。

提前谢谢你。

【问题讨论】:

  • 欢迎来到 Stack Overflow。请尽快阅读About 页面。 RS 是记录(行)分隔符;您是否认为您找到了一个好的字段分隔符?如果你的意思是记录分隔符,那么样本数据只有 3 条记录,第三条没有终止(第一个 RS STRING 之前的材料,两个标记之间的材料,以及第二个标记之后的材料)。您使用的 RS 字符串到底是什么?你到底是如何设置 RS 的?
  • 如前所述,我遇到的问题是设置一个不在一行开头的 RS。当我在一行的开头设置一个 RS 时,它会从该行中剥离,并且该行的 RS 之后的数据保持不变。但是,如果 RS 位于该行中的任何其他位置,则直到定义的 RS 的所有内容都将被删除。我想保留该数据。这个例子只是为了说明我想要完成的事情。
  • 尝试 sed 并将 RS STRING 替换为 null。示例:sed 's/RS STRING//'
  • 但 RS 是“行尾”的标志...
  • 我刚刚编辑了我的原始帖子以更好地说明我的问题。

标签: awk


【解决方案1】:

使用 awk 和空行作为记录分隔符

awk 'BEGIN{RS="";FS="RS_STRING"}
    /SEARCHED_STRING/{$1=$1;print $0 ORS}'  file

如果记录之间没有空行,并且 RS_STRING 总是在记录的第一行,那么试试这个:

awk '/RS_STRING/{i++}{a[i]=a[i]==""?$0:a[i]RS $0}
    END{for (j=1;j<=i;j++) if (a[j]~/SEARCHED_STRING/) print a[j]}' file

【讨论】:

  • 既然你已经有了BEGIN块,不如加上ORS="\n\n",把print语句中的ORS去掉。
  • @glennjackman 为什么?这有效,ORSORS="\n\n" 少 7 个字符。如果不需要,我通常不使用 BEGIN 块并在表达式后面添加变量以保存 -v 给它这样的 awk '/SEARCHED_STRING/ {$1=$1;print $0 ORS}' RS="" FS="RS_STRING" file
  • 有没有办法修改这个 awk 语法以使用 RS="RS_STRING" 而不是 ""?我问这个是因为我的输入在记录之间不一定有空行,RS 不能是除了 RS_STRING 之外的任何其他东西,以便获得所需的输出。
  • 如果没有空行,如何分组?有什么规则吗?你的意思是如果我看到 RS_STRING,这意味着该部分将从这一行开始?
  • 谢谢,第二个解决方案按预期工作。相当复杂的语法,将尝试破译它。
【解决方案2】:

一个非 awk 的答案

perl -00 -ne '/SEARCHED_STRING/ and do {s/RS_STRING//g; print}'

使用搜索字符串搜索段落并删除“rs”字符串。

【讨论】:

  • 谢谢,这个解决方案产生了预期的结果。你能解释一下语法吗?我很好奇它是如何正确分离记录的。我只能识别搜索模式 (SEARCHED_STRING) 和 RS_STRING 替换为空白。但是它怎么知道 RS_STRING 是我的记录分隔符呢?
  • 在 Perl 文档中找到这个:“特殊值 00 将导致 Perl 以段落模式 slurp 文件。任何值 0400 或以上都会导致 Perl slurp 整个文件,但按照惯例,值 0777 是通常用于此目的的一个。”不幸的是我不明白。
  • 有没有办法修改上述解决方案,以便专门用 RS_STRING 分隔记录?我的输入不一定在记录之间有空行,因此当我在实时数据上测试命令时,它包含一些信息,如果 RS 由 RS_STRING 定义,这些信息通常会被剥离。谢谢。
  • 只需阅读 Perl 的文档:“记住:$/ 的值是字符串,而不是正则表达式。awk 必须更好。:-)”这意味着如果我想定义带有正则表达式的 RS,我需要返回 awk :(
【解决方案3】:

它对我有用:

echo "ab RS_STRING cd" | awk '{print "NR="NR ": \""$0"\""}' RS="RS_STRING"

给出输出

NR=1: "ab "
NR=2: " cd
"

如您所见,除了字符串 "RS_STRING".. 之外,没有任何部分被剥离。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多