linux - AWK 处理数据直到下一次匹配
问题描述
我正在尝试使用 awk 处理文件。样本数据:
233;20180514;1;00;456..;m
233;1111;2;5647;6754;..;n
233;1111;2;5647;2342;..;n
233;1111;2;5647;p234;..;n
233;20180211;1;00;780..;m
233;1111;2;5647;3434;..;n
233;1111;2;5647;4545;..;n
233;1111;2;5647;3453;..;n
问题陈述是说我需要复制匹配“1;00;”的记录的第二列 跟踪记录直到下一个“1;00;” 匹配,然后进一步复制该记录的第二列,直到下一个“1;00;” 匹配。匹配模式“1;00;” 也可以改变。可以说“2;20;” . 在这种情况下,我需要复制第二列,直到出现“1;00;” 或“2;20;” 匹配。
我可以使用 while 循环来做到这一点,但我真的需要使用 awk 或 sed 来做到这一点,因为文件很大而且 while 可能需要很长时间。
预期输出:
233;20180514;1;00;456..;m
233;20180514;1111;2;5647;6754;..;n+1
233;20180514;1111;2;5647;2342;..;n+1
233;20180514;1111;2;5647;p234;..;n+1
233;20180211;1;00;780..;m
233;20180211;1111;2;5647;3434;..;n+1
233;20180211;1111;2;5647;4545;..;n+1
233;20180211;1111;2;5647;3453;..;n+1
提前致谢。
解决方案
编辑:由于 OP 已更改有问题的示例 Input_file,因此现在根据新示例添加代码。
awk -F";" '
length($2)==8 && !($3=="1" && $4=="00"){
flag=""}
($3=="1" && $4=="00"){
val=$2;
$2="";
sub(/;;/,";");
flag=1;
print;
next
}
flag{
$2=val OFS $2;
$NF=$NF"+1"
}
1
' OFS=";" Input_file
基本上检查 8 的第二个字段的长度以及第三个和第四个字段的长度是否为 NOT1
和0
条件,而不是检查;1;0
.
如果您的实际 Input_file 与显示的示例相同,那么以下内容可能会对您有所帮助。
awk -F";" 'NF==5 || !/pay;$/{flag=""} /1;00;$/{val=$2;$2="";sub(/;;/,";");flag=1} flag{$2=val OFS $2} 1' OFS=";" Input_file
解释:
awk -F";" ' ##Setting field separator as semi colon for all the lines here.
NF==5 || !/pay;$/{ ##Checking condition if number of fields are 5 on a line OR line is NOT ending with pay; if yes then do following.
flag=""} ##Setting variable flag value as NULL here.
/1;00;$/{ ##Searching string /1;00; at last of a line if it is found then do following:
val=$2; ##Creating variable named val whose value is $2(3nd field of current line).
$2=""; ##Nullifying 2nd column now for current line.
sub(/;;/,";"); ##Substituting 2 continous semi colons with single semi colon to remove 2nd columns NULL value.
flag=1} ##Setting value of variable flag as 1 here.
flag{ ##Checking condition if variable flag is having values then do following.
$2=val OFS $2} ##Re-creating value of $2 as val OFS $2, basically adding value of 2nd column of pay; line here.
1 ##awk works on concept of condition then action so mentioning 1 means making condition TRUE and no action mentioned so print will happen of line.
' OFS=";" Input_file ##Setting OFS as semi colon here and mentioning Input_file name here.
推荐阅读
- google-chrome - 为什么 Chrome 开发工具控制台会在我阅读它们之前立即清除所有消息
- azure-devops - 如何在 VSTS API 中删除带注释的标签(git 标签)?
- c# - 在 asp.net mvc 5 中发送带有附件 Pdf 问题的电子邮件
- c++ - typedef 模板参数推导失败?
- java - 无法运行 Junit 案例。引发错误“实际上与此模拟的交互为零”
- java - 了解 android MVP 中的漏洞
- python - 使用struct在python3.6中读取结构化二进制数据
- regex - 如何在位置标签中提取 Apache httpd.conf 中的参数值?
- python-2.7 - 张量流 1.11 和 cuda 8
- python - 在二进制文件中查找模式?