Как удалить первое двоеточие ':' из отметки времени?

10

Я новичок в программировании!

Может ли кто-нибудь помочь удалить :на первой позиции в отметке времени::29.06.2019 23:03:17

В настоящее время я пытаюсь сделать это с помощью команд awk / cut, как показано ниже:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

И выход не то, что я хотел! Я хочу напечатать это как 29.06.2019 23:03:17.

Манодж Кумар
источник

Ответы:

14

Чтобы отрезать первый символ, вы также можете использовать cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17
pLumo
источник
11

использование

cut -d: -f2-

вместо того

cut -d: -f2

получить что-нибудь от второго поля до конца строки:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"
Флориан Диш
источник
8

awkэто крутой инструмент, и вы можете решать очень сложные задачи с ним. Но для вашего вопроса я бы предпочел придерживаться базовых возможностей bash.

Для этого легкого удаления подстановки я бы сделал следующее:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

это напечатает:

29.06.2019 23:03:17

Когда я оказался на вашем месте и начал изучать программирование и bash, я многое узнал из этого Руководства:

ABS - Расширенное руководство по написанию сценариев

Еще несколько примеров и интересной информации по вашей проблеме можно найти здесь , ищите «Удаление подстроки».

Ханнес Моргенштерн
источник
3
+1 это! Поскольку вопрос помечен как «bash», следует подумать о том, что он предпочитает большие (хотя часто и довольно смутные) возможности bash для манипулирования строками, которые намного быстрее, чем загрузка внешних инструментов.
Рекскогитанс
2
@rexkogitans, так как мы уже вызываем grep или awk для разбора файла, bash не будет быстрее. На самом деле, когда вам нужно разобрать файл, bash будет работать медленно. Все снаряды медленные, а удар медленнее, чем у большинства. Тем не менее, возможности командной строки для работы со строками действительно часто являются лучшим подходом, но только если у вас уже есть входные данные в качестве переменной.
тердон
8

Вот sedрешение:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

Команда sed 's/^://'выполняет замену sсимвола двоеточия :в начале ^каждой строки пустой строкой //.

Вот хитрое awkрешение, в котором мы меняем разделитель полей ^:, как описано выше, и выводим второе поле (каждой строки):

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

Задача может быть выполнена также с grep( объяснением ), возможно, это может быть самым быстрым решением для большого количества данных:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Или обработайте файл напрямую с помощью следующей команды, в ^которой снято ограничение :

grep -Po 'Logfile started :\K.*' process.log

Вышесказанное может быть достигнуто также sedи группами захвата ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

Где выражение ^.*<something>.*$будет соответствовать всей строке, которая содержит <something>. Команда s/old/new/заменит эту строку содержимым первой группы захвата (выражение в скобках может быть более конкретным). Опция -rвключает расширенные регулярные выражения. Опция -nподавит нормальный вывод sedи, наконец, команда pнапечатает совпадения.

pa4080
источник
Я никогда не знал, что awkмог бы иметь многосимвольную FS с персонажами со специальным значением! То, что я узнал сегодня.
Флорис
6

Поскольку вы уже обрабатываете это awk, вы можете сделать все это напрямую:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

В subцелом формат команды является sub(/REGEX/, REPLACEMENT, TARGET)и заменит все матчи для регулярного выражения REGEXсо строкой REPLACEMENTво входной строке TARGET. Здесь мы заменяем первое :( ^означает «начало») из 3-го поля ( $3) ничем.

Конечно, если вы делаете это в awk, вы можете также сделать все в awk и выполнить все это за одну операцию:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Или, в вашем случае:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"
terdon
источник
0

Другое решение Bash:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Это использует конвейер вместо промежуточного назначения переменных.
  • Команда xargsпреобразует stdin(стандартный ввод) в позиционные параметры для bashкоманды.
  • Заменить echoна tail -n1 /path/to/reportfile.txt.
WinEunuuchs2Unix
источник