Как убрать миллисекунды с отметок времени с помощью sed? - PullRequest
1 голос
/ 18 декабря 2011

Мой входной файл выглядит следующим образом:

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 ]

5 голосов
/ 18 декабря 2011
sed 's/\(:[0-9][0-9]\)\.[0-9]\{3\}/\1/g' input_file.csv > output.csv

Вы были почти там.В классическом sed вы должны использовать обратную косую черту перед скобками и скобками, чтобы превратить их в метасимволы.Некоторые версии sed могут иметь механизм для инвертирования операций, так что скобки и скобки по умолчанию являются метасимволами, но это не надежно для разных платформ.

Также (сильная рекомендация): используйте одинарные кавычки вокруг sedкоманда.В противном случае оболочка получает трещину при интерпретации этих обратных слешей (и любых знаков $ и т. Д.) До того, как sed увидит их.Обычно это смущает кодера (и особенно кодера поддержки).На самом деле, используйте одинарные кавычки вокруг аргументов программ, когда вы можете.Не впадайте в паранойю - если вам нужно интерполировать переменную, сделайте это.Но одиночные кавычки, как правило, легче кодировать и, в конечном счете, легче понять.

Я решил работать только с одной единицей времени;ты работал над тремя.В конечном итоге, учитывая систематически сформированные входные данные, в результате нет разницы - но есть (небольшая) разница в читаемости сценария.

2 голосов
/ 18 декабря 2011

Попробуйте:

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

Также попробуйте \d вместо [0-9], ваша версия sed может поддерживать это.

1 голос
/ 18 декабря 2011

Вы были рядом, но некоторые символы особенные в 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 голосов
/ 19 декабря 2011

Поскольку решение 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, мы будем делать substitution с полями, когда for loop анализирует второе и третье поля.
  4. Если поля не 2-го и 3-го, то мы просто распечатываем поля.
  5. Наконец, поскольку мы использовали for loop для <NF, мы просто выводим $NF, которое является последним полем. Это не приведет к печати , после последнего поля.
0 голосов
/ 18 декабря 2011

Это может работать для вас:

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