String 使用sed从配置文件中提取某些字符串

String 使用sed从配置文件中提取某些字符串,string,awk,sed,String,Awk,Sed,我正在尝试从下面的输出导出某些字符串,但是我没有使用sed/awk的经验,我需要一些建议如何继续 输入: name Cleartext-Password := "password", Service-Type := Framed-User Framed-IP-Address := 127.0.0.1, MS-Primary-DNS-Server := 8.8.8.8, Fall-Through = Yes, Mikrotik-Rate-Limi

我正在尝试从下面的输出导出某些字符串,但是我没有使用sed/awk的经验,我需要一些建议如何继续

输入:

name Cleartext-Password := "password", Service-Type := Framed-User
    Framed-IP-Address := 127.0.0.1,
    MS-Primary-DNS-Server := 8.8.8.8,
    Fall-Through = Yes,
    Mikrotik-Rate-Limit = 20M/30M
输出应为: 名称暗语127.0.0.1;20M;30米

我不确定这样做是否正确,但我已尝试删除所需字符串之间的所有内容,例如:

sed 's/ Cleartext-Password := "/;/' 
然而,我认为这是肮脏的方式,而不是聪明的方式


您能告诉我需要寻找什么,以便为此创建有效的sed/awk解决方案吗?

您能根据显示的示例尝试以下内容吗。现场编写并测试

由于OP的输入_文件具有控制M个字符,因此在这里的代码中添加了gsub/\r/

awk '
BEGIN{ OFS=";" }
{ gsub(/\r/,"") }
match($0,/Cleartext-Password[^,]*/){
  val=substr($0,RSTART,RLENGTH)
  gsub(/Cleartext-Password[^"]*|"/,"",val)
  val=$1 OFS val
  next
}
/Framed-IP-Address/{
  sub(/,$/,"")
  val=val OFS $NF
  next
}
/Mikrotik-Rate-Limit/{
  print val, $NF
  val=""
}' Input_file
说明:在程序的开始部分,根据问题将S设置为分号。然后使用awk的match函数从字符串Cleartext…Cleartext Password[^,]*匹配正则表达式,直到出现第一个逗号。如果正则表达式完全匹配,那么在这里捕获变量val中的子字符串。现在使用gsub全局替换所有内容,从明文密码到所有不必要的内容,都是根据需要输出的

然后检查该行是否包含带边框的IP地址(若找到),然后发送替换,从行的最后一行开始,并将该行的最后一个字段添加到变量val中


现在检查条件,如果一行包含Mikrotik速率限制,则只需在此处打印val值和最后一个字段,并在此处使val无效。

请根据显示的示例尝试以下操作。现场编写并测试

由于OP的输入_文件具有控制M个字符,因此在这里的代码中添加了gsub/\r/

awk '
BEGIN{ OFS=";" }
{ gsub(/\r/,"") }
match($0,/Cleartext-Password[^,]*/){
  val=substr($0,RSTART,RLENGTH)
  gsub(/Cleartext-Password[^"]*|"/,"",val)
  val=$1 OFS val
  next
}
/Framed-IP-Address/{
  sub(/,$/,"")
  val=val OFS $NF
  next
}
/Mikrotik-Rate-Limit/{
  print val, $NF
  val=""
}' Input_file
说明:在程序的开始部分,根据问题将S设置为分号。然后使用awk的match函数从字符串Cleartext…Cleartext Password[^,]*匹配正则表达式,直到出现第一个逗号。如果正则表达式完全匹配,那么在这里捕获变量val中的子字符串。现在使用gsub全局替换所有内容,从明文密码到所有不必要的内容,都是根据需要输出的

然后检查该行是否包含带边框的IP地址(若找到),然后发送替换,从行的最后一行开始,并将该行的最后一个字段添加到变量val中


现在检查条件,如果一行包含Mikrotik速率限制,则只需在此处打印val值和最后一个字段,并在此处将val置零。

有许多方法可以使用awk实现这一点,关键是将记录的一部分与正则表达式相匹配,以标识正在操作的记录,然后以所需的格式隔离所需的测试和输出

一种办法是:

awk '
    /Cleartext-Password/ { printf "%s;%s;", $1, substr($4,2,length($4)-3) }
    /Framed-IP-Address/  { printf "%s;", substr($NF,1,length($NF)-1) }
    /Mikrotik-Rate-Limit/{ sub(/\//,";",$NF); printf "%s;\n", $NF }
' config
示例使用/输出

使用名为config的文件中的示例输入,您将收到:

name;password;127.0.0.1;20M;30M;

仔细检查一下,如果我在任何地方误解了,请告诉我。

使用awk有很多方法可以做到这一点,关键是将部分记录与正则表达式相匹配,以标识您正在操作的记录,然后以所需的格式隔离所需的测试和输出

一种办法是:

awk '
    /Cleartext-Password/ { printf "%s;%s;", $1, substr($4,2,length($4)-3) }
    /Framed-IP-Address/  { printf "%s;", substr($NF,1,length($NF)-1) }
    /Mikrotik-Rate-Limit/{ sub(/\//,";",$NF); printf "%s;\n", $NF }
' config
示例使用/输出

使用名为config的文件中的示例输入,您将收到:

name;password;127.0.0.1;20M;30M;

仔细检查一下,如果我在任何地方误解了,请告诉我。

这可能适用于您GNU sed:

sed -nE -e '/Cleartext-Password/{s/ .*:=\s"(.*)",.*/;\1/;h}' \
        -e '/Framed-IP-Address/{s/.*:= (.*),/\1/;H}' \
        -e '/Mikrotik-Rate-Limit/{s#.*= (.*)/(.*)#\1;\2#;H;g;y/\n/;/;p}' file
通过调用-n选项关闭隐式打印

通过调用-E选项减少反斜杠

将记录的字段隐藏在保留空间中,收集完所有字段后,将保留空间复制到模式空间,用字段分隔符替换换行符并打印结果

您可能更喜欢:

sed -nE '/Cleartext-Password/{s/ .*:=\s"(.*)",.*/;\1/;h};
         /Framed-IP-Address/{s/.*:= (.*),/\1/;H};
         /Mikrotik-Rate-Limit/{s#.*= (.*)/(.*)#\1;\2#;H;g;y/\n/;/;p}' file

这可能适用于GNU sed:

sed -nE -e '/Cleartext-Password/{s/ .*:=\s"(.*)",.*/;\1/;h}' \
        -e '/Framed-IP-Address/{s/.*:= (.*),/\1/;H}' \
        -e '/Mikrotik-Rate-Limit/{s#.*= (.*)/(.*)#\1;\2#;H;g;y/\n/;/;p}' file
通过调用-n选项关闭隐式打印

通过调用-E选项减少反斜杠

将记录的字段隐藏在保留空间中,收集完所有字段后,将保留空间复制到模式空间,用字段分隔符替换换行符并打印结果

您可能更喜欢:

sed -nE '/Cleartext-Password/{s/ .*:=\s"(.*)",.*/;\1/;h};
         /Framed-IP-Address/{s/.*:= (.*),/\1/;H};
         /Mikrotik-Rate-Limit/{s#.*= (.*)/(.*)#\1;\2#;H;g;y/\n/;/;p}' file

只有一个样本,很难说什么是足够的,但5-6行Awk似乎是合适的。如果代币总是按可预测的顺序排列,则可能更少。同样地,不幸的是,这是一个关于堆栈溢出的模糊问题。名称是包含空格的名称的关键字还是占位符?您的文件始终有5行?@cyrus name始终是一个不带空格的字符串,但它可以在其中包含点或其他特殊字符。这被标记为[tageembedded linux],但您没有提到任何平台。如果你在Busybox这样的平台上需要这个,也许是为了澄清你的需求。添加3-4条记录和你想要的输出,但你的问题中没有对该样本输入的描述。只有一个样本,很难说什么是足够的,但5-6行Awk似乎就是一张罚单。如果代币总是按可预测的顺序排列,则可能更少。像

不幸的是,这是一个关于堆栈溢出的模糊问题。名称是包含空格的名称的关键字还是占位符?您的文件始终有5行?@cyrus name始终是一个不带空格的字符串,但它可以在其中包含点或其他特殊字符。这被标记为[tageembedded linux],但您没有提到任何平台。如果你在Busybox这样的平台上需要这个,也许是为了澄清你的需求。在你的问题中添加3-4条记录和你想要的输出,没有关于这个示例输入的描述。用手机写的这篇文章将在早上添加完整的解释,因为现在已经是深夜了:;20M/30m;127.0.0.1,-这是我在debian上测试的输出lab@jakeiscool,对不起,我没有得到它,如果你检查我的解决方案中提到的我的链接,它对我很好,你能告诉我你在这里是否有任何错误吗?每行末尾有^M个字符,先生,现在它像一个符咒一样工作。非常感谢你。遗憾的是,我甚至不知道如何开始理解您的解决方案是如何工作的。对我来说,这看起来很复杂也很难。我有很多东西要学。。再次感谢您在手机上写下这篇文章将在早上补充完整的解释,因为现在已经很晚了:;20M/30m;127.0.0.1,-这是我在debian上测试的输出lab@jakeiscool,对不起,我没有得到它,如果你检查我的解决方案中提到的我的链接,它对我很好,你能告诉我你在这里是否有任何错误吗?每行末尾有^M个字符,先生,现在它像一个符咒一样工作。非常感谢你。遗憾的是,我甚至不知道如何开始理解您的解决方案是如何工作的。对我来说,这看起来很复杂也很难。我有很多东西要学。。再次感谢您谢谢先生,我确信我的问题将被删除,但我感谢您和其他用户为帮助我所做的一切努力。我将检查您的解决方案是如何工作的,然后尝试理解其中的每一部分。将为您提供所使用的所有功能。/match stuff/{…}只是确保{…}之间的内容只应用于包含匹配内容的行。祝您的脚本编写工作顺利。谢谢您,先生,我确信我的问题将被删除,但我感谢您和其他用户为帮助我所做的一切努力。我将检查您的解决方案是如何工作的,然后尝试理解其中的每一部分。将为您提供所使用的所有功能。/match stuff/{…}只是确保{…}之间的内容只应用于包含匹配内容的行。祝你的脚本编写工作好运。你好!我已经测试了您的解决方案,但是它似乎与RavinderSingh13完全一样。它会剪切密码和第一个字符串,可能是因为^M存在于我的测试文件中。请检查:尝试运行dos2unix你好!我已经测试了您的解决方案,但是它似乎与RavinderSingh13完全一样。它会剪切密码和第一个字符串,可能是因为^M存在于我的测试文件中。请检查:尝试运行dos2unix