awk:使用gensub替换段落记录中的多行

时间:2019-02-25 19:49:29

标签: regex awk substitution

我有一个输入文件,其中的多个段落至少由两个换行符(\n\n)隔开,并且我想从某些段落中的行中提取字段。我认为,如果我能按我的意愿使gensub正常工作,处理将是最简单的。考虑以下输入文件:

[Record R1]
    Var1=0
    Var2=20
    Var3=5

[Record R2]
    Var1=10
    Var3=9
    Var4=/var/tmp/
    Var2=12

[Record R3]
    Var1=2
    Var3=5
    Var5=19

我只想打印记录Var2R1(其中R3实际上不存在)中的Var2的值。我可以通过设置RS="\n\n"轻松地将所有变量分组到它们相应的记录中,然后将它们全部包含在$0中。但是由于我不知道它会在列表的前面出现,所以我想使用gensub之类的东西来提取它。这就是我要去的:

awk '
    BEGIN {
        RS="\n\n"
    }
    /Record R1/ || /Record R3/ {
        print gensub(/[\n.]*Var2=(.*)[\n.]*/, "\\1", "g", $0)
    }
' /tmp/input.txt

但是,它不仅打印20(R1中Var2的值),还打印以下内容:

[Record R1]
    Var1=0
    20
    Var3=5
[Record R3]
    Var1=2
    Var3=5
    Var5=19

目的是gensub命令中的正则表达式将捕获\n之前和之后的所有字符(换行符:.;非换行符:Var2=XX),并将所有内容替换为{ {1}}。取而代之的是,它仅捕获与XX在同一行上的字符。 Var2=XX的{​​{1}}可以进行这种多行替换吗?

我知道一种替代方法是遍历记录中的所有字段,将与awk符号上的gensub匹配的字段拆分,但是随着将其扩展到多个变量。

2 个答案:

答案 0 :(得分:2)

我不明白您正在尝试使用gensub()做什么,但是要在任何awk中执行的工作似乎是:

  static navigationOptions = {
    title: "Profile",
    headerStyle: {
      backgroundColor: "#4169E1"
    },
    headerTintColor: "white",
    headerRight: (
      <Button
      onPress={() => removeItem()}
      title="Disconnect"
      color="white"
      />
    )
  };

gensub()不在乎它所操作的字符串是一行还是多行-export async function removeItem() { console.log("navigate => ", this.props); await AsyncStorage.removeItem("login"); console.log("item login removed"); navigate("Home") //something like that return ; } 仅是一个字符,与其他任何字符都没有区别。

哦,等等,现在我明白了您对gensub()的想法-您的问题是:

  1. awk -F'[][[:space:]=]+' '{f[$2]=$3} !NF{if (f["Record"]~/^R[12]$/) print f["Var2"]; delete f}' file 20 12 awk -F'[][[:space:]=]+' '{f[$2]=$3} !NF{if (f["Record"]~/^R[13]$/) print f["Var2"]; delete f}' file 20 的意思是\n,但您没有 输入中的任何句号,因此与[\n.]*相同,但是在zero or more newlines or periods之前没有换行符
  2. \n*在第二条记录中不存在,因此正则表达式无法匹配它。
  3. Var2将使所有内容匹配到记录的末尾(最长的匹配项)。
  4. Var2具有误导性,因为您只期望有1个匹配项。

因此在多行文本上使用gensub()并不是问题,您的正则表达式是错误的。

答案 1 :(得分:0)

另一个awk

$ awk -v RS= '/\[Record R[13]\]/{for(i=2;i<=NF;i++)
                                   {v=sub(/ *Var2=/,"",$i);
                                    if(v) print $i}}' file

20