替换重叠的文本
Substituting text that overlaps
我有一段数据(data.txt),由于用户的错误,看起来像这样:
4,48
4485
4,49
4495
4,5
4505
4,51
4,6
11445
11,45
模式是这样的:只要有逗号,0 就会被删除。所以:4450被不当改成了4,45,4600改成了4,6;和 11450 更改为 11,45.
因此,找到逗号时应执行两个操作:
- 在右边加一两个0,得到逗号右边的三位数字:
d,dd -> d,dd0 ;或者 d,d -> d,d00
- 删除逗号
ddd0 ; dd00
最终结果应该是:
4480
4485
4490
4495
4500
4505
4510
4600
11445
11450
如何在 sed(或其他程序)上使用正则表达式来获得此结果?
- 一种解决方案是将数据拆分为两个文件,dataa.txt 和 datab.txt:
dataa.txt:
4,48
4485
4,49
4495
4,5
4505
4,51
4,6
11445
11,45
和datab.txt:
4,5
4,6
第一个文件:
$ sed -E 's/(\,[0-9][0-9])//g;s/\,//g' dataa.txt
第二个文件:
$ sed -E 's/(\,[0-9])/0/g;s/\,//g' datab.txt
然后,连接文件。如果没有这些额外的步骤(拆分和连接),这样做会更好。
使用awk有很好的解决方案(谢谢!),转载如下:
$ awk '{gsub(/,/, ""); printf "%.4s\n", $0 * 1000}' data.txt
但是在处理 5 位数字时(您可以根据逗号左侧的位数找到它们)它也不起作用。它还需要拆分数据。
我们如何在不拆分数据的情况下获得最终结果?
(为清楚起见进行了编辑)
使用 GNU awk:
如果当前行包含 ,
将其值乘以 1000。
LC_NUMERIC=de_DE.UTF-8 awk --use-lc-numeric '/,/{[=10=]=[=10=]*1000} {print}' file
或更短
LC_NUMERIC=de_DE.UTF-8 awk --use-lc-numeric '/,/{[=11=]*=1000}1' file
输出:
4480
4485
4490
4495
4500
4505
4510
4600
与awk
:
$ awk '{gsub(/,/, ""); printf "%.4s\n", [=10=] * 1000}' ip.txt
4480
4485
4490
4495
4500
4505
4510
4600
gsub(/,/, "")
删除所有逗号字符
[=13=] * 1000
将数字乘以 1000
printf "%.4s\n"
只打印前四位数字
首先确保逗号后有足够的数字。接下来删除第三个小数点后的所有内容并删除逗号:
sed -r 's/(,.*)/00/; s/,(...).*// ' data.txt
注意:00
记住与 </code> 匹配的字符串 1 并添加 <code>000
.
$ awk 'split(,d,/,/)>1 { [=10=]=sprintf("%-*d",length(d[1])+3,d[1]d[2]); gsub(/ /,0) } 1' file
4480
4485
4490
4495
4500
4505
4510
4600
11445
11450
我可以使用正则表达式来解决:它缺少锚点“$”。 sed:
单行代码
sed -E 's/(\,[0-9]$)//g;s/(\,[0-9][0-9])//g;s/\,//g' data.txt
以前,我使用的是 \,[0-9]
,它与此数据不明确,并且匹配 4,5 和 4,51。正则表达式 \,[0-9]$
仅匹配 4,5,而不匹配 4,55。要匹配 4,51 我们可以使用 \,[0-9][0-9]
.
感谢 awk 解决方案,非常优雅并且使用了不同的方法。
我有一段数据(data.txt),由于用户的错误,看起来像这样:
4,48
4485
4,49
4495
4,5
4505
4,51
4,6
11445
11,45
模式是这样的:只要有逗号,0 就会被删除。所以:4450被不当改成了4,45,4600改成了4,6;和 11450 更改为 11,45.
因此,找到逗号时应执行两个操作:
- 在右边加一两个0,得到逗号右边的三位数字: d,dd -> d,dd0 ;或者 d,d -> d,d00
- 删除逗号 ddd0 ; dd00
最终结果应该是:
4480
4485
4490
4495
4500
4505
4510
4600
11445
11450
如何在 sed(或其他程序)上使用正则表达式来获得此结果?
- 一种解决方案是将数据拆分为两个文件,dataa.txt 和 datab.txt:
dataa.txt:
4,48
4485
4,49
4495
4,5
4505
4,51
4,6
11445
11,45
和datab.txt:
4,5
4,6
第一个文件:
$ sed -E 's/(\,[0-9][0-9])//g;s/\,//g' dataa.txt
第二个文件:
$ sed -E 's/(\,[0-9])/0/g;s/\,//g' datab.txt
然后,连接文件。如果没有这些额外的步骤(拆分和连接),这样做会更好。
使用awk有很好的解决方案(谢谢!),转载如下:
$ awk '{gsub(/,/, ""); printf "%.4s\n", $0 * 1000}' data.txt
但是在处理 5 位数字时(您可以根据逗号左侧的位数找到它们)它也不起作用。它还需要拆分数据。
我们如何在不拆分数据的情况下获得最终结果?
(为清楚起见进行了编辑)
使用 GNU awk:
如果当前行包含 ,
将其值乘以 1000。
LC_NUMERIC=de_DE.UTF-8 awk --use-lc-numeric '/,/{[=10=]=[=10=]*1000} {print}' file
或更短
LC_NUMERIC=de_DE.UTF-8 awk --use-lc-numeric '/,/{[=11=]*=1000}1' file
输出:
4480 4485 4490 4495 4500 4505 4510 4600
与awk
:
$ awk '{gsub(/,/, ""); printf "%.4s\n", [=10=] * 1000}' ip.txt
4480
4485
4490
4495
4500
4505
4510
4600
gsub(/,/, "")
删除所有逗号字符[=13=] * 1000
将数字乘以1000
printf "%.4s\n"
只打印前四位数字
首先确保逗号后有足够的数字。接下来删除第三个小数点后的所有内容并删除逗号:
sed -r 's/(,.*)/00/; s/,(...).*// ' data.txt
注意:00
记住与 </code> 匹配的字符串 1 并添加 <code>000
.
$ awk 'split(,d,/,/)>1 { [=10=]=sprintf("%-*d",length(d[1])+3,d[1]d[2]); gsub(/ /,0) } 1' file
4480
4485
4490
4495
4500
4505
4510
4600
11445
11450
我可以使用正则表达式来解决:它缺少锚点“$”。 sed:
单行代码sed -E 's/(\,[0-9]$)//g;s/(\,[0-9][0-9])//g;s/\,//g' data.txt
以前,我使用的是 \,[0-9]
,它与此数据不明确,并且匹配 4,5 和 4,51。正则表达式 \,[0-9]$
仅匹配 4,5,而不匹配 4,55。要匹配 4,51 我们可以使用 \,[0-9][0-9]
.
感谢 awk 解决方案,非常优雅并且使用了不同的方法。