Як видалити першу двокрапку ":" із позначки часу?


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

11

Використовуйте

cut -d: -f2-

замість

cut -d: -f2

щоб отримати що-небудь від другого поля до кінця рядка:

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

8

awkце класний інструмент, і ви можете вирішити дуже складні завдання з ним. Але для вашого питання я б скоріше дотримувався основних можливостей баш.

Для цього простого видалення підстановок я б зробив наступне:

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

це надрукує:

29.06.2019 23:03:17

Коли я був на вашому становищі і почав вивчати програмування та баш, я дізнався багато цього посібника:

ABS - розширений посібник із написання сценарію

Ще кілька прикладів та цікавої інформації щодо вашої проблеми можна знайти тут , шукайте "Видалення підрядків".


3
+1 Це! Оскільки питання позначене "bash", слід вважати за краще віддати перевагу великим (хоча часто досить незрозумілим) можливостям керування струнами, які набагато швидше, ніж завантаження зовнішніх інструментів.
rexkogitans

2
@rexkogitans, оскільки ми вже закликаємо grep чи awk для розбору файлу, 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надрукує відповідність.


Я ніколи не знав, чи 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) нічим.

Звичайно, якщо ви робите це дивним способом, ви також можете зробити все в курсі і зробити все це за одну операцію:

$ 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"

0

Ще одне баш-рішення:

$ 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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.