2011-12-18 89 views
1

我的輸入文件如下:如何使用sed從時間戳中刪除毫秒?

12/13/2011,07:14:13.724,12/13/2011 07:14:13.724,231.56.3.245,LasVegas,US 

我希望得到如下:

12/13/2011,07:14:13,12/13/2011 07:14:13,231.56.3.245,LasVegas,US 

我想這一點,但沒有成功:

sed "s/[0-9]{2}\:[0-9]{2}\:[0-9]{2}\(\.[0-9]{1,3}\)/\1/g" input_file.csv > output.csv 

回答

5
sed 's/\(:[0-9][0-9]\)\.[0-9]\{3\}/\1/g' input_file.csv > output.csv 

你我們快到了。在經典的sed中,你必須在括號和大括號前面使用反斜槓來將它們變成元字符。 sed的某些版本可能有反轉操作的機制,因此默認情況下,大括號和括號是元字符,但跨平臺不可靠。

另外(強烈推薦):圍繞sed命令使用單引號。否則,在sed看到它之前,shell會解釋這些反斜槓(以及任何$標誌等)。通常情況下,編碼器(尤其是維護編碼器)會造成混淆。事實上,只要有可能,就在程序中使用單引號。不要對此產生偏執 - 如果你需要插入一個變量,那就這樣做。但單引號通常更容易編碼,並且最終易於理解。

我選擇在一個時間單位上工作;你在三個工作。最終,系統地形成輸入數據後,結果沒有區別 - 但腳本的可讀性存在(很小的)差異。

+0

謝謝喬納森。這工作正常,但現在wodering爲什麼我的正則表達式沒有做到這一招... – SCO 2011-12-18 17:55:43

+0

看到我放大的答案... – 2011-12-18 17:57:43

+0

精確的答案,深入解釋我的錯誤,大起來!謝謝 ! – SCO 2011-12-18 18:04:50

2

嘗試:

sed 's,\(:[0-9]\{2\}\).[0-9]\{3\},\1,g' 

另外,儘量\d而不是[0-9],你sed的版本可以支持。

+0

我相信你必須避開大括號(即'\ {','\}'),但是看起來不錯。 – 2011-12-18 17:57:49

+0

@MansoorSiddiqui哎呀... – fge 2011-12-18 17:59:05

+0

是的,一旦逃脫,正常工作!謝謝 ! – SCO 2011-12-18 18:02:43

1

你是接近但有些字符在sed特殊(在我的版本,至少):{}(),但不:。所以你需要用反斜線來逃避它們。

\1表現在各個遺物之間,它應該是第一部分,直到秒,而不是第二部分。

您版本的修改可能是:

sed "s/\([0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)\.[0-9]\{1,3\}/\1/g" input_file.csv > output.csv 
0

這可能會爲你工作:

sed 's/\....//;s/\....//' input_file.csv >output_file.csv 
0

由於sed解決方案已經發布,這裏是一個替代awk解決方案:

[jaypal:~/Temp] cat inputfile 
12/13/2011,07:14:13.724,12/13/2011 07:14:13.724,231.56.3.245,LasVegas,US 

[jaypal:~/Temp] awk -F"," -v ORS="," ' 
{for(i=1;i<NF;i+=1) 
if (i==2||i==3) {sub(/\..*/,"",$i);print $i} 
else print $i;printf $NF"\n"}' inputfile 
12/13/2011,07:14:13,12/13/2011 07:14:13,231.56.3.245,LasVegas,US 

說明:

  1. 設置字段分隔符,和輸出記錄分隔符來,
  2. 使用for loop我們將遍歷每個字段。
  3. 使用if loop我們會對for loop解析第二個和第三個字段時的字段做substitution
  4. 如果字段不是2nd和3rd,那麼我們只是打印出字段。
  5. 最後,由於我們使用了for loop作爲<NF,我們只打印出$NF這是最後一個字段。這不會導致在最後一個字段後打印,
相關問題