【问题标题】:Replace a particular string (at fixed position) in a text file by line number用行号替换文本文件中的特定字符串(在固定位置)
【发布时间】:2019-11-17 23:44:24
【问题描述】:

我构建了一个脚本 (bash) 来替换 .txt 文件中特定位置的图形。

这是文件,data.txt:

Date; Buy; Sell; Coupon; Fee
21/6/2019;0.0000000000;0.0000000000;0.0000000000

我想替换第 12 个字符。

如果第 12 位等于“0”,则在代码部分下方找到更改位置的部分,将数字更改为“59”

sed 's/^\(.\{11\}\)0/\159/' data.txt

到目前为止一切顺利,问题是当我只想对最后一行 (#34) 进行更改时,将文件 (data.txt) 映像为:

Date; Buy; Sell; Coupon; Fee
26/4/2006;0.0000000000;-200000000.0;0.0000000000
4/5/2006;0.0000000000;-100000000.0;0.0000000000
4/5/2006;0.0000000000;-300000000.0;0.0000000000
1/12/2006;0.0000000000;0.0000000000;-30000000.00
5/12/2006;0.0000000000;-250000000.0;0.0000000000
8/12/2006;0.0000000000;-250000000.0;0.0000000000
19/12/2006;0.0000000000;-650000000.0;0.000000000
18/1/2007;0.0000000000;-250000000.0;0.0000000000
1/2/2007;0.0000000000;-250000000.0;0.0000000000
2/2/2007;0.0000000000;-720000000.0;0.0000000000
28/3/2007;0.0000000000;-200000000.0;0.0000000000
28/3/2007;0.0000000000;-400000000.0;0.0000000000
3/5/2007;0.0000000000;-250000000.0;0.0000000000
3/5/2007;0.0000000000;-750000000.0;0.0000000000
3/5/2007;0.0000000000;-250000000.0;0.0000000000
5/6/2007;0.0000000000;-500000000.0;0.0000000000
3/7/2007;0.0000000000;-300000000.0;0.0000000000
3/12/2007;0.0000000000;0.0000000000;-281000000.0
1/12/2008;0.0000000000;0.0000000000;-281000000.0
1/12/2009;0.0000000000;0.0000000000;-281000000.0
1/12/2010;0.0000000000;0.0000000000;-281000000.0
5/4/2011;525000000.00;0.0000000000;0.0000000000
1/12/2011;0.0000000000;0.0000000000;-254750000.0
2/11/2012;1348000000.0;0.0000000000;0.0000000000
2/11/2012;840000000.00;0.0000000000;0.0000000000
3/12/2012;0.0000000000;0.0000000000;-145350000.0
2/12/2013;0.0000000000;0.0000000000;-145350000.0
1/12/2014;0.0000000000;0.0000000000;-145350000.0
1/12/2015;0.0000000000;0.0000000000;-145350000.0
1/12/2016;0.0000000000;0.0000000000;-145350000.0
1/12/2017;0.0000000000;0.0000000000;-145350000.0
3/12/2018;0.0000000000;0.0000000000;-145350000.0
21/6/2019;0.0000000000;0.0000000000;0.0000000000

我使用了以下内容:

#!/bin/bash

i=1
while read line;do
if((i==34));then
sed 's/^\(.\{11\}\)0/\159/' data.txt
fi
((i++))

似乎条件有问题,脚本运行永不停止,没有输出就像一个没有结束的循环。

【问题讨论】:

  • 请按照论坛规则将您的示例/代码包装在 CODE TAGS 中,然后编辑您的帖子并让我们知道。
  • 替换第十二个字符会产生不一致的结果,因为您的第一个字段(日期)是可变长度的。请编辑您的问题以包含您想要的确切输出。
  • 大家好,我现在编辑了我的帖子。感谢您的帮助。
  • @LorenzoCastagno 请编辑您的问题以包含所需的确切输出。

标签: bash text sed replace


【解决方案1】:

试试这个:

sed '$s/^\([^;]\+;\)0\(.*\)/\159\2/' input

地址$ 告诉sed 只在文件的最后一行工作。与其替换第 12 个字符,不如替换第一个 ; 之后的字符。

bash 分割sed 的行绝对没有意义。循环线是sed 的核心功能之一。

【讨论】:

  • 捕获行尾(0之后)是没用的。
  • @CasimiretHippolyte 为什么?他说:“我想替换第 12 个字符。”
  • 你应该提到 \+ 需要 GNU sed 但是如果你必须使用 GNU sed 那么你可以使用像 sed -E '$s/^([^;]+;)0(.*)/\159\2/' 这样的 ERE 来避免这么多的转义然后在 OSX/ BSD sed 也是。如果你想要一个 POSIX 版本,那就是sed '$s/^\([^;]\{1,\};\)0\(.*\)/\159\2/'。 @CasimiretHippolyte 是对的,你不需要第二个捕获组,你只需要sed -E '$s/^([^;]+;)0/\159/'
  • @LorenzoCastagno 运行echo 'abc' | sed 's/b/X/',它会输出aXc。现在运行echo 'abc' | sed 's/b\(.*\)/X\1/',它也会输出aXc。现在问问自己 - 在第二个脚本中编写 \(.*\)\1 以捕获您感兴趣的部分之后剩下的内容有什么好处?答案是否定的,就像这个答案中的脚本一样。
  • 确实 sed '$s/^\([^;]*;\)0/\159/' 做同样的事情(不必描述行尾)。
【解决方案2】:

以下适用于gawkmawkoriginal-awkbusybox

awk 'END {if(int($2)==0) $2=59; print}' {O,}FS=\; data.txt

输出:

21/6/2019;59;0.0000000000;0.0000000000

在最后一条记录(行)上,awk 检查第二个分号 ; 分隔字段的整数值,如果等于 0,则将其更改为 59。

【讨论】:

  • 这依赖于未定义的行为,因为 POSIX 未定义 $0 部分中 $0 的值。在某些 awks 中,它将是最后一次读取的 $0 的值,在其他情况下,它将为 null,而在其他情况下,它可能是/做其他任何事情。它会在 GNU awk 中做你想做的事,其他人都知道。
  • @EdMorton 我针对mawkgawkoriginal-awk 进行了测试。以低标准为基础放弃一个可行的解决方案是很荒谬的。我非常想知道您是否找到不这样做的版本。
  • HP-UX awk 是一个(请参阅stackoverflow.com/q/29970249/1745001)。另请参阅gnu.org/software/gawk/manual/… - all of BWK awk, mawk, and gawk preserve the value of $0 for use in END rules. Be aware, however, that some other implementations and many older versions of Unix awk do not. 对此的讨论。我并不是建议您放弃该解决方案,只是在 END 部分中提到它只会在支持 $0 等的 awk 中按预期运行。
  • @EdMorton 有价值的信息;对于我必须处理的旧 NAC,我会牢记这一点。
  • 知道NAC 是什么,但不要认为这只是旧 UNIX 安装或 awk 版本的问题,因为 awk 手册说“一些其他实现和许多旧版本Unix awk 的版本没有。” - 这不仅仅是“许多旧版本”。只要记住说“如果...有效”,如果/当你指望这个,那么一切都很好。
猜你喜欢
  • 2021-12-28
  • 2014-08-19
  • 2020-11-12
  • 2014-06-21
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多