Удаление букв и точек со всех строк

У меня есть CSV, который выводит команды time для разных программ, включая идентификатор выполнения.

Поэтому мои файлы содержат записи в следующем виде:

ID,execution_time

Пример записи:

345,0m0.047s

Мне нужен только номер выполнения и номер секунд.

Поэтому вышеупомянутая запись должна быть

345,0047 (без «0m» «.» и «s»).

[d6 ] Можно ли это достичь?

1
задан 3 July 2014 в 02:32

4 ответа

Что делать, если есть минуты, а? Вот один из них, который учитывает это, преобразовывая их в секунды:

awk -F'[m,]' '{print $1 "," $2*60 + $3}' file.csv

И несколько демо:

$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s")
345,0.047
345,60.047
345,62.047

Я не уверен, почему вы когда-либо захотите удалить десятичную точку, но вы можете передать результат через sed 's/\.//g', если вам это действительно нужно:

$ ... <(echo -e "345,0m0.047s\n345,1m0.047s\n345,1m2.047s") | sed 's/\.//g'
345,0047
345,60047
345,62047

Eugh.

И, учитывая это, выход time - что, если значение содержит часы или даже дни? Я немного поиграл и придумал этот маленький краситель:

awk -F'[dhms,]' 'BEGIN{split("1 60 3600 86400", T, " ")}{t=0; for (i=NF-1; i>1; i--) t+=T[NF-i]*$i; printf("%s,%.3f\n", $1, t)}'

Это будет обрабатывать следующие форматы: *s *m*s *h*m*s и *d*h*m*s и конвертировать их все в секундах (до трех знаков после запятой). Обязательное демонстрационное время:

$ ... <(echo -e "345,1.2s\n345,12m5s\n345,1h2m5s\n345,1d2h1m2.047s")
345,1.200
345,725.000
345,3725.000
345,93662.047
10
ответ дан 24 May 2018 в 06:05
  • 1
    Я тоже. Я думаю. :) – kraxor 2 July 2014 в 14:01
  • 2
    @kraxor Ваш не умножает их на 60, но вы просто оставляете минутное значение в начале секунд. – Oli♦ 2 July 2014 в 14:05
  • 3
    Ничего себе, очень хороший ответ. Упрощенный :) Спасибо! – Jim Blum 2 July 2014 в 14:07
  • 4
    @ Оли, ты прав. Думаю, я взял «количество секунд». буквально. OP также сказал «с 0m». +1 для вас, хотя для более общего решения. – kraxor 2 July 2014 в 14:14

Должно быть:

sed 's/m0\.\(.*\)s$/\1/g'

4
ответ дан 24 May 2018 в 06:05
  • 1
    Оооо !!! Большое спасибо Ярону! Upvoted :) и как я это делаю, если у моего файла несколько записей? – Jim Blum 2 July 2014 в 13:54
  • 2
    Я попробовал это на этой записи «5234,0m1.022s», но я думаю, что не могу заставить ее работать – Jim Blum 2 July 2014 в 13:58
  • 3
    Просто напишите их по строкам в файле (вы можете сделать это, используя ваш любимый текстовый редактор или автоматически используя функцию конкатенации bash, а затем просто введите cat myfile.txt | sed... или sed -i.bak sed ... myfile.txt, надейтесь, что он отлично работает для вас :) – Yaron 2 July 2014 в 13:58
  • 4
    Конечно, @JimBlum имеет 1. в нем и скрипт только удаляет 0., дайте мне еще несколько примеров, и я попытаюсь сделать что-то более общее (исходный и желаемый результат, конечно) – Yaron 2 July 2014 в 14:00

Еще один через awk,

awk -F, -v OFS="," '{gsub(/0m/,"",$2);gsub(/\./,"",$2);gsub(/s/,"",$2); print $1,$2}' file

Пример:

$ echo '345,0m0.047s' | awk -F, -v OFS="," '{gsub(/0m/,"",$2);gsub(/\./,"",$2);gsub(/s/,"",$2); print $1,$2}'
345,0047

И соответствующий,

$ echo '345,52m0.047s' | awk -F, -v OFS="," '{gsub(/^.*?m/,"",$2);gsub(/\./,"",$2);gsub(/s/,"",$2); print $1,$2}'
345,0047
1
ответ дан 24 May 2018 в 06:05

Ответ @kraxor использует sed, чтобы удалить «все остальное» из строки, а затем просто показать строку.

Но - что на самом деле «все остальное»? Здесь у нас есть идея, по крайней мере, из одной строки выборки. Но что, когда мы получаем строку заголовка CSV? Что удалить? В общем, мы не знаем.

Поэтому на самом деле лучше «все остальное» !

echo '345,0m0.047s' | sed -n -r 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/\1,\2\3/p'

345,0047

Работает до сих пор!

Ответ @kraxor использует sed, чтобы удалить «все остальное» из строки, а затем просто показать строку.

Теперь некоторые другие вход, довольно нормальный, с двумя строками данных:

ID,execution_time
123, Oops a comment0m0.0333s
345,0m0.047s

Huh ?! Похоже на другой вход, довольно нормальный , на самом деле!

echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed -r -n 's/^(.*),.*[^0-9]([0-9]*)\.(.*)s$/\1,\2\3/p'

123,00333
345,0047

Выглядит хорошо и правильно!

Чтобы показать, что это имеет некоторые достоинства, чтобы сделать это таким образом, я сравню с более ранним ответом:

echo "ID,execution_time\n123, Oops a comment0m0.0333s\n345,0m0.047s" | sed 's/[0-9]*m\|s\|\.//g'

ID,execution_tie
123, Oop a coent00333
345,0047

Ok , фактические, чистые линии передачи данных прошли хорошо;

(Обратите внимание, что есть решение явно пропускать строку заголовка (или, может быть, первую строку данных, мы знаем?))

1
ответ дан 24 May 2018 в 06:05

Другие вопросы по тегам:

Похожие вопросы: