(sed 或 sh 中的替代方法)如果一行不包含点 (.)。然后在最后添加XX

(sed 或 sh 中的替代方法)如果一行不包含点 (.)。然后在最后添加XX

背景信息:两个程序之间通过 csv 进行数据交换。

我有来自程序 1 的以下 csv:

> timestamp; name ; value 
> 1655709562;Var 1 Float;65.0 
> 1655709562;Var 2 Float;3.32 
> 1655709562;Var 1 Integer;**2** 
> 1655709562;Var 2 Integer;**564**

对于程序 2,我必须将其转换为以下内容,因为它始终期望“值”具有相同的日期类型:

timestamp; name ; value
1655709562;Var 1 Float;65.0
1655709562;Var 2 Float;3.32
1655709562;Var 1 Integer;**2.0**
1655709562;Var 2 Integer;**564.0**

我将尝试用 for 循环和 if 函数来展示它,因为我认为这是展示它的最佳方式。

for $line in $file
do
 If $line contains NOT "." 
  then
    add ".0" at the end of line
 end_if
done

答案1

在 中sed,其语法为:

sed '/\./!s/$/.0/' < file.in > file.out

也就是说,如果当前行不是( !) 匹配\.正则表达式(文字点),s用 替换正则表达式的第一个匹配项$$匹配行尾)XX

awk与:相同

awk '! index($0, ".") {$0 = $0 ".0"}
     {print}' < file.in > file.out

这里用于 index()进行子字符串搜索。您还可以进行正则表达式匹配,例如 with sedwith ! /\./

perl

perl -lpe '$_ .= ".0" if index($_, ".") < 0' < file.in > file.out

或者使用正则表达式:

perl -lpe '$_ .= "XX" unless /\./' < file.in > file.out

使用perl,您可以添加选项-i来就地编辑文件(在这种情况下,您必须将其路径作为参数传递,而不是在其标准输入上打开它)。一些sed实现借用了该选项。最近版本的 GNU 实现awk-i /usr/share/awk/inplace.awk1 来实现这一点。

在所有这些中, a.0也会添加到标题行,因为该行也不包含.s。

也许更好的方法是添加.0如果行结尾;后跟一个或多个十进制数字:

sed '/;[0123456789]\{1,\}$/ s/$/.0/'

或者用一些seds:

sed -E '/;[0123456789]+$/ s/$/.0/'
awk '/;[0123456789]+/{$0 = $0 ".0"}
     {print}'
perl -lpe '$_ .= ".0" if /;\d+$/'

^不使用-i inplaceas尝试首先从当前工作目录gawk加载inplace扩展(asinplace或),有人可能已经在其中植入了恶意软件。随系统提供的扩展inplace.awk的路径可能会有所不同,请参阅输出inplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

相关内容