2014-02-08 128 views
1

我有此文件在CSV文件与AWK替换列值

error.log中

[00:00:00.284],501,

[00:00:00.417] ,5,5294100071980

[00:00:02.463],501,

[00:00:05.169],501,

[00:00:05.529],501,

[00:00:05.730],501,

所以,如果字段$ 3其空我想打印 “没有价值”

我试着这个代码

awk '{{FS=","} if($3=="") {print $1,$2,"No value"}}' 

但它打印

>[00:00:00.284] 501 No value 
>[00:00:02.463] 501 No value 
>[00:00:05.169] 501 No value 
>[00:00:05.529] 501 No value 
>[00:00:05.730] 501 No value 
>[00:00:07.193] 501 No value 
>[00:00:09.899] 501 No value 
>[00:00:31.312] 501 No value 
+1

你真的在输入文件中的每个真实数据行之间有空行? –

回答

8
awk -F ',' -v OFS=',' '$1 { if ($3=="") $3="No value"; print}' in.txt 
  • 通过-F选项传递字段分隔符。
  • 变量OFS(输出字段分隔符)设置为,,因此输出字段也由,分隔。
  • 模式$1确保只处理非空行(即,只有在第一个字段非空时才执行关联操作) - 如果输入文件没有空行,则可以删除此模式
  • 如果第三个字段为空,则会分配字符串“无值”
  • 最后,输出该行(带有可能被修改的第三个字段)。

以上是我建议你解决这个问题,但在这里与您的原始命令的问题:里面的单个动作

  • {{FS=","}... - 这是由于没有之前的模式执行对于每个输入行 - 您为每行设置变量FS- 这不仅是不必要的,而且太迟,因为第一个输入行在那段时间已经被解析(谢谢,@EdMorton) - 要么将它设置为BEGIN块(BEGIN { FS="," }),或者如我的答案,命令行选项-F-F ',')。
  • if($3=="") {...}
    如果场$3是空的您只产生输出 - 大概,但是,你要输出所有线,所以用这种方法你需要一个else分支(打印未修改线)。
  • print $1,$2,"No value"
    , chars。这里是语法的一部分 - 它们将传递给print的参数分开。给定单独的参数,print将它们与特殊的OFS变量的值连接在一起,默认值为单个空间;若要使用,代替,则必须将其分配给OFS-再次,可以在BEGIN块中或通过-v选项(-v OFS=',')再次将其分配给OFS
+1

'{FS =“,”} ... [功能上不是问题,但是效率低下]是一个问题,因为直到输入文件的第一行使用默认值FS分割为字段后才会执行。 –

+1

@EdMorton好点,谢谢 - 答案更新。 – mklement0

+1

我们可以从发布的输入中看出,$ 3可以是数字,我们知道他希望在空白时打印“No value”,但他并没有说它不能具有数字值0,所以测试'!$ 3 '与测试“空”不一样,那就是'$ 3 ==“”''。 –

2

您应该发布一些预期的输出,但我想你想要的是:

awk 'BEGIN{FS=OFS=","} NF{print $1, $2, ($3=="" ? "No value" : $3)}' file 
+1

+1为优雅。 (唯一需要注意的是 - 如果需要泛化)是解决方案仅限于3个输出列)。 – mklement0

2

有了这个文件

cat file 
[00:00:00.284],501, 
[00:00:00.417],5,5294100071980 
[00:00:02.463],501, 
[00:00:05.169],501, 
[00:00:05.529],501, 
[00:00:05.730],501, 

awk应该做

awk -F, '$3=="" {$3="No value"}1' OFS=, file 
[00:00:00.284],501,No value 
[00:00:00.417],5,5294100071980 
[00:00:02.463],501,No value 
[00:00:05.169],501,No value 
[00:00:05.529],501,No value 
[00:00:05.730],501,No value 
+0

+1简明;我很好奇你为什么选择伪文件名形式'OFS =',通过选项形式'-V OFS =', - 只需输入便利性?语义是微妙的不同,但在这种情况下,他们的工作原理是一样的。 (另外,你认为没有空行 - 这可能是一个公平的假设。) – mklement0

+0

只是为了保存三个字符:)'-v'没有其他原因。 – Jotne