克服奇怪的sed行为

时间:2016-08-29 15:16:48

标签: bash sed

我有一个输出文件已经获得了以下值

16.1
144.3
352.5
23.4
129.5
993.9

我还有一个包含以下文字的源文件。

#0  abc 2016-08-06 01:12:57 AM  9.1%    779.9M of 1G    156.3M of 1G
#1  abc 2016-08-06 02:33:47 AM  12.1%   339.9M of 1G    126.3M of 1G

使用grep,我在#0和#1行上运行循环,并在第一次迭代时将以下内容存储在变量中。

$cpu #stores 9.1
$mem #stores 779.9
$disk #stores 156.3

下一次,我的grep循环遍及"#1"我的3个变量将更新为12.1,339.9和126.3。

我尝试使用sed获取输出如下

16.1,9.1
144.3,779.9
352.5,156.3
23.4,12.1
129.5,339.9
993.9,126.3

我在循环中使用以下sed代码来执行此操作。

sed ""$counter"s/$/,"$cpu"/" "$opFile" | tee "$opFile"
((counter++))
sed ""$counter"s/$/,"$mem"/" "$opFile" | tee "$opFile"
((counter++)
sed ""$counter"s/$/,"$disk"/" "$opFile" | tee "$opFile"

我使用tee的原因是因为没有它,我在脚本中运行时会得到这样的输出

16.1,9.1
144.3
352.5
23.4
129.5
993.9
16.1
144.3,779.9
352.5
23.4
129.5
993.9

依旧等等。我希望你能看到发生了什么。

Tee为我提供了正确的答案,但有时只能起作用但行为很奇怪。在命令行中,有时它会正确附加到所有6行。另一次,它附加到5行,然后只是使opFile为空。还有一次,在第一次尝试时,它使opFile变空。忘记命令行,在执行我的脚本结束时,每次我的opFile都是空白的。

为什么会这样?

2 个答案:

答案 0 :(得分:3)

$ cat output.txt
16.1
144.3
352.5
23.4
129.5
993.9

$ cat source.txt
#0  abc 2016-08-06 01:12:57 AM  9.1%    779.9M of 1G    156.3M of 1G
#1  abc 2016-08-06 02:33:47 AM  12.1%   339.9M of 1G    126.3M of 1G

$ paste -d, output.txt <(grep -oP '[0-9.]+(?=%)|[0-9.]+(?=[A-Z]+ of)' source.txt)
16.1,9.1
144.3,779.9
352.5,156.3
23.4,12.1
129.5,339.9
993.9,126.3

这个替代解决方案可能有用,我不知道你的方法有什么不对......

修改

$ paste -d, output.txt <(grep -oP '[0-9.]+(?=%)|[0-9.]+(?=[A-Z]+ of)' source.txt) > tmp ; mv tmp output.txt

这会将输出保存在tmp文件中,然后移至output.txt

答案 1 :(得分:2)

我还没有完全遵循你想要做的事情,但你不应该阅读和写入同一个文件 - 这可能是你的问题所在。

当您将输出文件指定为tee时,它将被打开以进行写入和截断。如果sed在此之前有机会读取文件,那么事情似乎就会起作用。但是,情况并非总是如此。

可能会简化您的整体流程,但使用临时文件至少可以解决问题。

例如:

sed ""$counter"s/$/,"$disk"/" "$opfile" | tee "${opfile}_tmp" && mv "${opfile}_tmp" "$opfile"