Команда sed для замены символов

Это используется для globbing весь текущий путь. Если Вы имеете -path '*bin/*rch' и Вы в настоящее время смотрите на /sbin/ausearch затем это будет соответствовать.

5
18.11.2018, 12:04
6 ответов
sed -e 's/\(..\)\/\(..\)\/\(....\),\(.....\),\(.*\)/\3-\1-\2 \4:00,\5/'

Редактировано с учетом следующих замечаний:

sed -e 's#\(..\).\(..\).\(....\),\(.....\),#\3-\1-\2 \4:00,#'
6
27.01.2020, 20:32

Это сработало:

sed -r 's/([0-9]{2})\/([0-9]{2})\/([0-9]{4}),([0-9:]{5})/\3-\1-\2 \4:00/g'

Совпадают 2 цифры (([0-9]{2})), слэш, 2 цифры (([0-9]{2})), слэш, 4 цифры (([0-9]{4})), а затем цифры и : (([0-9:]{5})). Замените его на тот, который хотите: \3-\1-\2 \4:00 (год-месяц-день час:минута:00).

3
27.01.2020, 20:32

Я бы предложил немного другой подход - разобрать временную метку, а затем выплюнуть форматированную временную метку. И я бы использовал perl для этого:

#!/usr/bin/perl

use strict;
use warnings;

use Time::Piece;

my $input_format  = '%m/%d/%Y,%H:%M';
my $output_format = '%Y-%m-%d %H:%M:%S';

while (<>) {
    my ( $date, $time, @stuff ) = split(",");
    my $timestamp = Time::Piece->strptime( "$date,$time", $input_format );
    print join( ",", $timestamp->strftime($output_format), @stuff );
}

Который можно сократить до одного лайнера, таким образом:

perl -MTime::Piece -lne '($date,$time,@stuff) = split; print join ( ',', Time::Piece->strptime( "$date,$time", "%m/%d/%Y,%H:%M" ) -> strftime("%Y-%m-%d %H:%M:%S"), @stuff);'

Который с вашими данными выборки выплёвывает:

1998-01-02 09:45:00,0.4592,0.4613,0.4529,0.4571,9956023
1998-01-02 10:00:00,0.4571,0.4613,0.455,0.4613,8939555
1998-01-02 10:15:00,0.4613,0.4697,0.4571,0.4697,12823627
1998-01-02 10:30:00,0.4676,0.4969,0.4613,0.4906,28145145
2
27.01.2020, 20:32
sed 'y|/|-|
     s/,*\(.....\)-*\([^,]*\)/\2-\1/
     s// \1:00/2
'    <infile

ВЫВОД:

1998-01-02 09:30:00,0.4571,0.4613,0.4529,0.4592,6042175
1998-01-02 09:45:00,0.4592,0.4613,0.4529,0.4571,9956023
1998-01-02 10:00:00,0.4571,0.4613,0.455,0.4613,8939555
1998-01-02 10:15:00,0.4613,0.4697,0.4571,0.4697,12823627
1998-01-02 10:30:00,0.4676,0.4969,0.4613,0.4906,28145145

С sed обычно не нужно так сильно стараться - часто попытки не окупаются для явного перечисления искомых совпадений. Скорее, гораздо проще просто указать несколько ориентиров - разделителей - и позволить шаблону съесть промежуточное время за вас.

Выше sed first y /// переводит символы / в символы - . Затем он ссылается на первый не-запятую (при условии, что их не менее 5) символ в пространстве шаблона и следующие четыре символа как \ 1 , возможно, игнорируя завершающий - . Это следует из ссылки на столько последовательных ^ не-запятых символов в \ 2 , сколько могло бы быть до следующей встречающейся запятой в пространстве шаблонов. В результате для первой замены mm-dd помещается в \ 1 перед сопоставлением - , а затем yyyy в \ 2 . Итак, мы меняем их местами, отбрасываем - и вставляем новый с другой стороны, например:

s/.../\2-\1/

И, наконец, мы делаем это снова - повторно используем тот же шаблон для другой цели.Когда я это сделаю:

s// \1:00/2

Я даю команду sed повторно использовать последнее регулярное выражение (как обозначено пустым адресом // ) , но на этот раз найти второе вхождение этого шаблона в пространстве шаблонов - которое действительно соответствует запятой с , * на этот раз - оно соответствует запятой, разделяющей это поле и последнее. Он также соответствует HH: MM в \ 1 и (поскольку за этой строкой сразу следует запятая) '' null- строка в \ 2 . Все, что осталось оттуда, это заменить \ 1 самим собой, которому предшествует , а за ним следует строка : 00 . И промежуточная запятая, и нулевая строка удаляются.

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

Если построение вашего регулярного выражения само по себе становится повторяющейся задачей, то, ну ... вероятно, чего-то не хватает. Однако одним из преимуществ простого синтаксиса регулярного выражения является то, что он также часто является очень хорошим кандидатом для абстракции - и это легко достигается.

Например:

d='[0-9][0-9]' T=$d:$d m=$d y=$d$d
sed -E "s|($m/$d)/($y),($T)|\2-\1 \3:00|;s|/|-|"
3
27.01.2020, 20:32

И возможное решение awk:

awk 'BEGIN { FS = OFS = ","; } { split($1, d, "/"); $2 = d[3] "-" d[1] "-" d[2] " " $2 ":00"; $1 = ""; } { for (i = 2; i < NF; i++) printf("%s", $i OFS); printf("%s", $NF ORS);}' file
2
27.01.2020, 20:32

Используйте следующее:

sed -n 's_^\([^/]*\)/\([^\]*\)/\([^,]*\),\([^:]*\):\([^,]*\)_\3-\1-\2 \4:\5:00_p' file.txt
1
27.01.2020, 20:32

Теги

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