Bash脚本 - 批量修改文件sed正则表达式

时间:2022-09-15 16:34:57

I have a set of .csv files (all in one folder) with the format shown below:

我有一组.csv文件(全部在一个文件夹中),格式如下所示:

170;151;104;137;190;125;170;108
195;192;164;195;171;121;133;104
... (a lot more rows) ...

The thing is I screwed up a bit and it should look like this

事情是我搞砸了一下,看起来应该是这样的

170;151;104.137;190.125;170;108
195;192;164.195;171.121;133;104 

In case the difference is too subtle to notice:

如果差异太微妙而无法注意到:

I need to write a script that changes every third and fifth semicolon into a period in every row in efery file in that folder.

我需要编写一个脚本,将每隔三和五分号更改为该文件夹中efery文件中每一行的句点。

My research indicate that I have to devise some clever sed s/ command in my script. The problem is I'm not very good with regular expressions. From reading the tutorial it's probably gonna involve something with /3 and /5.

我的研究表明,我必须在我的脚本中设计一些聪明的sed s / command。问题是我对正则表达式不是很好。从阅读教程开始,它可能会涉及/ 3和/ 5。

2 个解决方案

#1


4  

Here's a really short way to do it:

这是一个非常简短的方法:

sed 's/;/./3;s/;/./4' -iBAK *

It replaces the 3rd and then the 5th (which is now the 4th) instances of the ; with ..

它取代了第3个,然后是第5个(现在是第4个)实例;与......

I tested it on your sample (saved as sample.txt):

我在你的样本上测试了它(保存为sample.txt):

$ sed 's/;/./3;s/;/./4' <sample.txt
170;151;104.137;190.125;170;108
195;192;164.195;171.121;133;104

For safety, I have made my example back up your originals as <WHATEVER>.BAK. To prevent this, change -iBAK to -i.

为了安全起见,我将我的示例备份为 .BAK。要防止这种情况,请将-iBAK更改为-i。


This script may not be totally portable but I've tested it on Mac 10.8 with BSD sed (no idea what version) and Linux with sed (gsed) 4.1.4 (2003). @JonathanLeffler notes that it's standard POSIX sed as of 2008. I also just found it and like it a lot.

这个脚本可能不是完全可移植的,但我已经在Mac 10.8上使用BSD sed(不知道什么版本)和带有sed(gsed)4.1.4(2003)的Linux进行了测试。 @JonathanLeffler指出它是标准的POSIX sed截至2008年。我也刚刚找到它并喜欢它。


Golf tip: If you run the command from bash, you can use brace expansion to achieve a supremely short version:

高尔夫提示:如果你从bash运行命令,你可以使用大括号扩展来实现一个非常短的版本:

sed -es/\;/./{3,4} -i *

#2


1  

Here's one way:

这是一种方式:

sed -i 's/^\([^;]*;[^;]*;[^;]*\);\([^;]*;[^;]*\);/\1.\2./' foldername/*

(Disclaimer: I did test this, but some details of sed are not fully portable. I don't think there's anything non-portable in the above, so it should be fine, but please make a backup copy of your folder first, before running the above. Just in case.)

(免责声明:我测试了这个,但是sed的一些细节并不是完全可移植的。我不认为上面有任何不便携的东西,所以它应该没问题,但请先备份你的文件夹的备份运行以上。以防万一。)

#1


4  

Here's a really short way to do it:

这是一个非常简短的方法:

sed 's/;/./3;s/;/./4' -iBAK *

It replaces the 3rd and then the 5th (which is now the 4th) instances of the ; with ..

它取代了第3个,然后是第5个(现在是第4个)实例;与......

I tested it on your sample (saved as sample.txt):

我在你的样本上测试了它(保存为sample.txt):

$ sed 's/;/./3;s/;/./4' <sample.txt
170;151;104.137;190.125;170;108
195;192;164.195;171.121;133;104

For safety, I have made my example back up your originals as <WHATEVER>.BAK. To prevent this, change -iBAK to -i.

为了安全起见,我将我的示例备份为 .BAK。要防止这种情况,请将-iBAK更改为-i。


This script may not be totally portable but I've tested it on Mac 10.8 with BSD sed (no idea what version) and Linux with sed (gsed) 4.1.4 (2003). @JonathanLeffler notes that it's standard POSIX sed as of 2008. I also just found it and like it a lot.

这个脚本可能不是完全可移植的,但我已经在Mac 10.8上使用BSD sed(不知道什么版本)和带有sed(gsed)4.1.4(2003)的Linux进行了测试。 @JonathanLeffler指出它是标准的POSIX sed截至2008年。我也刚刚找到它并喜欢它。


Golf tip: If you run the command from bash, you can use brace expansion to achieve a supremely short version:

高尔夫提示:如果你从bash运行命令,你可以使用大括号扩展来实现一个非常短的版本:

sed -es/\;/./{3,4} -i *

#2


1  

Here's one way:

这是一种方式:

sed -i 's/^\([^;]*;[^;]*;[^;]*\);\([^;]*;[^;]*\);/\1.\2./' foldername/*

(Disclaimer: I did test this, but some details of sed are not fully portable. I don't think there's anything non-portable in the above, so it should be fine, but please make a backup copy of your folder first, before running the above. Just in case.)

(免责声明:我测试了这个,但是sed的一些细节并不是完全可移植的。我不认为上面有任何不便携的东西,所以它应该没问题,但请先备份你的文件夹的备份运行以上。以防万一。)