使用 sed 对第二次出现的情况进行“查找和替换”

使用 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

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

-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

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

因此我想到使用“查找和替换”仅有的第二个“点”如下。查找:

0.

用。。。来代替:

   0.

我不知道如何指定sed只对每行的“第二个点”执行操作。有人知道如何做到这一点吗?

答案1

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

* 贪婪的,会吃掉尽可能多的字符,因此\.总是匹配行的最后一个字符。确保第二个数字的[^-]可选项-进入第二组。

答案2

要仅替换第二次出现的情况,请使用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

怎么运行的:

  • -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

答案3

找到第一个点:)

sed -r 's/(.*\.[^-\.]*)(-?)0\.(.*)/\1\t\20.\3/' file

笔记

  • -r使用 ERE
  • s/old/newold用。。。来代替new
  • (some chars)保存some chars以供日后参考
  • .*任意数量的任意字符
  • \.文字.
  • [^-\.]除连字符或.
  • -?选修的-
  • \1\t\20.\3打印保存的图案、标签和0.正确的位置

答案4

怎么样

$ sed -E 's/(-?0\.[0-9]+)(-?0\.[0-9]+)/\1\t\2/' file
-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

怎么运行的:

  • -?0\.[0-9]+匹配0.后跟一个或多个其他十进制数字,并且可选地在前面加上-
  • (-?0\.[0-9]+)(-?0\.[0-9]+)捕获上述 2 个实例
  • \1\t\2用 TAB 替换它们

相关内容