Intereting Posts
Есть ли способ определить сигнал, который был пойман изнутри функции ловушки bash? Как сортировать файлы по части имени файла? Как вы получаете описания доступных опций `shopt`? Не удается открыть мой профиль Google Chrome Изменение suEXEC Path / CentOS 6 Как использовать и / или условно в сценарии оболочки Как вы проводите время, в течение которого команда выполнялась? Как включить кеширование пакетов в dnf? Могу ли я извлечь полную командную строку из файла данных поверх 1.23? Невозможно контролировать яркость на HP Pav dv6t, работающем на Fedora 16 Как открыть случайно закрытое окно терминала в сеансе VNC? Как запустить HAProxy на CentOS с помощью systemd Как загрузить пакеты из командной строки данного репозитория? Как сделать мой экран двухэкранным растяжением с Debian Jessie и Radeon RX460? Как распечатать разницу в двух текстовых файлах с помощью сценариев оболочки?

Как вырезать метки времени из файла?

У меня есть журнал, который содержит строки данных:

Mon Apr 20 03:15:18 EDT 2015: my|data|data|data 

Я пытаюсь написать сценарий, который будет извлекать только данные из журнала, удаляя ведущие метки времени:

 while read p do echo $p | sed "s/.* EDT $year: //g" > replay_message_$count.txt; count=$((count+1)); done < $fileName 

Прямо сейчас я использую шаблон .* EDT $year: где $year – это параметр, переданный пользователем.

Каким образом можно извлечь данные, не передавая год в качестве параметра?

Если вы знаете, что формат даты всегда будет содержать шесть разделенных пробелами полей, вы можете использовать:

 cut -d ' ' -f 7- 

Если вы знаете, что ваша метка времени всегда занимает 30 символов, вы можете использовать:

 cut -c 31- 

Если вы знаете, что ваши метки времени заканчиваются цифрой, за которой следует двоеточие, за которым следует пробел и что ваши данные не включают этот шаблон, вы можете использовать:

 sed 's/.*[0-9]: //' 

Если у вас есть более конкретные требования, вы можете их упомянуть.

Это предназначено для замены всего цикла while в вашем скрипте:

 awk '{print substr($0, 31)>("replay_message_" NR-1 ".txt")}' file 

Как это работает:

  • print substr($0, 31)

    Это печатает все, кроме первых тридцати символов строки.

  • >("replay_message_" NR-1 ".txt")

    Это отправляет то, что было напечатано в файле с именем после номера строки.

Когда команда awk будет завершена, в вашем каталоге будет серия файлов, например:

 $ ls -1 replay_message* replay_message_0.txt replay_message_1.txt replay_message_2.txt replay_message_3.txt 

Альтернатива в случае, если длина метки времени

 awk '{sub(/.* E[SD]T [[:digit:]]{4}: /, ""); print >("replay_message_" count++ ".txt")}' file 

Как это работает

awk неявно читает файл по одной записи (строке) за раз. Для каждой строки:

  • sub(/.* EDT [[:digit:]]{4}: /, "")

    Это удаляет временную метку с начала строки.

    Регулярное выражение соответствует всему пространству, часовому поясу (EST или EDT), пробелу, четырем цифрам за год, двоеточием и пробелом.

    В качестве альтернативы, если бы было гарантировано, что ваша метка времени имеет всего 30 символов, можно использовать более простую замену:

     sub(/.{30}/, "") 

    Основываясь на ваших входных файлах, вам нужно будет решить, что лучше всего подходит для вашей ситуации.

  • print >("replay_message_" count++ ".txt")

    Это записывает измененную строку в файл, который содержит номер count . ++ приводит к тому, что count увеличивается с каждой записью.