使用 sed 对第二次出现使用“查找和替换”

Hun*_*ter 4 command-line bash text-editor sed

我有一个包含 +1000 .dat 文件的文件夹。每个文件包含许多以下类型的行:

-0.0999999999999659-0.0000000006287859
-0.08999999999997500.8000000006183942
-0.0799999999999841-0.0000000007463807
-0.06999999999999320.0000000008661516
-0.06000000000000230.0000000008640644
-0.05000000000001140.0000000008807621
-0.0400000000000205-0.7000000009575896
-0.02999999999997270.0000000009476864
-0.01999999999998180.0000000009150902
-0.00999999999999090.0000000008144152
0.00000000000000000.0000000007097434
0.00999999999999090.0000000007847500
0.01999999999998180.0000000009030998
0.03000000000002960.0000000009741985
Run Code Online (Sandbox Code Playgroud)

对于我想将其转换为的所有文件

-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985
Run Code Online (Sandbox Code Playgroud)

在所有这些文件中唯一一致的是第二个数字(对应于每行的第二个点)总是小于 1.0 并大于 -1.0。但是第一个数字可以取任何实际值。

因此,我想到仅对第二个“点”使用“查找和替换” ,如下所示。找:

0.
Run Code Online (Sandbox Code Playgroud)

用。。。来代替:

   0.
Run Code Online (Sandbox Code Playgroud)

我不知道如何指定sed只对每一行的“第二个点”进行操作。有没有人对如何完成这项工作有一个好主意?

Flo*_*sch 5

 sed -E s'/(.*[^-])(-?0\.)/\1    \2/' 999.dat
Run Code Online (Sandbox Code Playgroud)

The* 是贪婪的并且会尽可能多地吃掉字符,因此\.匹配始终是该行的最后一个。在[^-]确保了可选的-所述第二数量的进入第二组。


Joh*_*024 5

要仅替换第二次出现,请使用2修饰符。因此:

$ sed -E 's/-?[[:digit:]][.]/    &/2' file.dat
-0.0999999999999659    -0.0000000006287859
-0.0899999999999750    0.8000000006183942
-0.0799999999999841    -0.0000000007463807
-0.0699999999999932    0.0000000008661516
-0.0600000000000023    0.0000000008640644
-0.0500000000000114    0.0000000008807621
-0.0400000000000205    -0.7000000009575896
-0.0299999999999727    0.0000000009476864
-0.0199999999999818    0.0000000009150902
-0.0099999999999909    0.0000000008144152
0.0000000000000000    0.0000000007097434
0.0099999999999909    0.0000000007847500
0.0199999999999818    0.0000000009030998
0.0300000000000296    0.0000000009741985
Run Code Online (Sandbox Code Playgroud)

这个怎么运作:

  • -E

    这告诉 sed 使用扩展的正则表达式。这消除了逃避?.

  • s/-?[[:digit:]][.]/ &/2

    这会寻找一个可选的-后跟一个数字后跟一个文字.。在替换文本中,在匹配的字符串之前添加四个空格,表示&为 。

    2替换命令末尾的修饰符告诉 sed 只替换第二次出现的模式。

相关例子

更多的例子展示了如何进行不同的替换:

$ echo aaaa | sed 's/a/A/1'
Aaaa
$ echo aaaa | sed 's/a/A/2'
aAaa
$ echo aaaa | sed 's/a/A/3'
aaAa
$ echo aaaa | sed 's/a/A/4'
aaaA
$ echo aaaa | sed 's/a/A/g'
AAAA
Run Code Online (Sandbox Code Playgroud)