【问题标题】:Extract data from one file and save to another从一个文件中提取数据并保存到另一个文件
【发布时间】:2020-01-03 18:03:27
【问题描述】:

我正在运行 ansible playbook 任务,使用 shell 命令根据正则表达式匹配从文件中提取数据并将其保存到另一个文件中。

我尝试使用 awk 和 sed 但无法使正则表达式正常工作。

awk '$NF == "-m.comment.*\""' iptable.txt" > file1.txt
sed 's/\/.*' iptable.txt > file2.txt

我需要将 -m comment 中的任何内容保存到双引号。到 file1.txt,其余内容到 file2.txt。如果该行没有注释字段,则应仅将其保存到 file2.txt。

-P INPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -m state --state NEW -m comment --comment "Echo Request" -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m comment --comment "tcp" -j ACCEPT

预期输出: 猫文件1.txt

-m comment --comment "Echo Request"
-m comment --comment "tcp"

cat file2.txt

-P INPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j ACCEPT

【问题讨论】:

  • 您的 AWK 脚本有不匹配的双引号。
  • 你的 sed 脚本语法错误
  • @JUSHJUSH 我正在尝试提取双引号,因此我将双引号作为匹配字符。你能指出我正确的 sed 语法吗?
  • wrt I know regex is right as I tested with regex tester - 证明正则表达式在某些在线工具中有效仅证明它在该在线工具中有效。这并不意味着它可以在 sed、awk 或任何其他命令行工具中工作。正则表达式变体、工具变体、扩展、分隔符、选项等太多了,以至于您认为可以在 foo 中测试正则表达式,这意味着它可以在 bar 中工作。

标签: regex awk sed text-parsing


【解决方案1】:

使用 GNU awk 将第三个参数匹配():

awk 'match($0,/(.*)(-m.comment.*")(.*)/,a) {
    print a[2] " > foo"
    print a[1] a[3] " > bar"
}' file
-m comment --comment "Echo Request" > foo
-A INPUT -p icmp -m state --state NEW  -j ACCEPT > bar

使用任何 awk:

awk 'match($0,/-m.comment.*"/) {
    print substr($0,RSTART,RLENGTH) " > foo"
    print substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH) " > bar"
}' file

只需将 " > foo" 更改为 > "foo" 并同上 bar 即可真正写入新文件。

如果这不是您所需要的,请编辑您的问题以阐明您的要求并提供更具代表性的示例输入/输出。

哦,当你写的时候:

$NF == "-m.comment.*\""

-m.comment.*\" 作为正则表达式本身没有任何问题,但 == 告诉 awk 进行文字字符串比较,而不是正则表达式比较。

鉴于您更新的问题,只需将上述调整为:

awk 'match($0,/(.*)(-m.comment.*")(.*)/,a) {
    print a[2] " > foo"
    print a[1] a[3] " > bar"
    next
}
{ print $0 " > bar" }' file
-P INPUT ACCEPT > bar
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT > bar
-m comment --comment "Echo Request" > foo
-A INPUT -p icmp -m state --state NEW  -j ACCEPT > bar
-m comment --comment "tcp" > foo
-A INPUT -p tcp -m state --state NEW  -j ACCEPT > bar

【讨论】:

  • 添加了更多信息。正如我所提到的,我将使用 ansible shell 模块运行它。提取的内容应保存到另一个文件中。
  • 好的,我调整了答案,将不包含comment 的行打印为bar
  • 谢谢埃德。但是现在bar只有一行没有commentfoo是空的。
  • 那么您要么尝试使用 GNU awk 解决方案,但实际上并未运行 GNU awk,要么您的实际输入与您发布的示例不同。
  • 我没有使用 GNU awk。但我对其进行了调整并使其正常工作awk 'match($0,/(.*)(-m.comment.*")(.*)/,a) {print a[2] > "bar"}' iptable.txt awk 'match($0,/(.*)(-m.comment.*")(.*)/,a) {print a[1] a[3]> "bar1"}' iptable.txt awk 'match($0,/(.*)(-m.comment.*")(.*)/,a) { next; } { print > "bar2" }' iptable.txt
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
相关资源
最近更新 更多