2014-02-08 127 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