我有一个输入文件,其中的多个段落至少由两个换行符(\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
我只想打印记录Var2
和R1
(其中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
匹配的字段拆分,但是随着将其扩展到多个变量。
答案 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()的想法-您的问题是:
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
之前没有换行符\n*
在第二条记录中不存在,因此正则表达式无法匹配它。Var2
将使所有内容匹配到记录的末尾(最长的匹配项)。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