我有多个文件,其中我必须仅截断模式@TEST 和enabled="true"> 之间的行。当存在匹配时,@TEST
和之间的字符串enabled="true">
应该只有 50 个字符。所有其他线路应保持不变。
例子:
@TEST-TC_0010 @TEST 验证 RADIUS 计费服务器在从 RADIUS 客户端接收到计费请求数据包时不应发送计费响应消息"enabled="true">
我必须更改上面的行,如下所示。
@测试-TC_0010@测试验证 RADIUS 计费服务器不应启用=“真”>
答案1
在这种情况下,您可以将 grep 与 Perl 环视结合使用。
grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile
表达式“(?<=)”标记匹配开始的点,表达式“(?=)”标记匹配结束的点。
“.*”告诉 grep 返回开始点和结束点之间的所有内容。
使用您的测试输入,上面的行返回 157 个字符。
$ echo "Verify that the RADIUS accounting server should not send the Accounting-Response Message on Receiving the Accounting-Request Packet from the RADIUS Client" | wc -m
157
如果您想进一步截断为仅前 50 个字符,您可以使用 cut
$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50
Verify that the RADIUS accounting server should no
如果您希望将结果保存到文件中,则需要将输出通过管道传输到另一个文件中。你可以使用类似下面的东西......
$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50 >> outputfile
我个人不建议覆盖输入文件,因为您可能在某些时候需要使用原始数据。
因此,如果您需要保留文件中的所有其他条目并仅截断启用=“true”的行,我们需要将工具更改为 awk。
$ awk -F'@TEST' '{if (/true/) print substr($3,2,50); else print $0}' inputfile >> outputfile
此 oneliner 将不做任何更改地输出与 true 不匹配的每一行。当 true 匹配时,该行将被截断为 50 个字符。我再次建议不要覆盖原始数据,以便将结果通过管道传输到输出文件中。
根据 OP 对问题所做的最新编辑,我修改了 awk 单行语句以复制 Beginner 提供的输出。他在评论中提到 awk 不起作用。在 OP 提供有关 awk 为何不起作用的更多详细信息之前,当在 Ubuntu 16.04 上使用 awk 4.1.3 时,以下行将返回他迄今为止详细说明的结果。
awk -F'@TEST' '{if (/true/) print "@TEST"$2,"@TEST",substr($3,2,50),"enabled=\"true\">"; else print $0}' inputfile >> outputfile