Мы можем использовать sed
или awk
полностью или полностью решить проблему.
С sed
:
$ sed 's/^.\./0&/' file.txt
Когда &
происходит в замещающей части команды подстановки ( s
), она будет расширена до той части строки ввода, которая соответствует шаблонной части команды.
Регулярное выражение ^.\.
означает « соответствовать всем строкам, начинающимся с ( ^
) произвольного символа ( .
), за которым следует буквальная точка ( \.
) ».
Если линия есть 1.02.2017 23:40:00
, шаблон будет соответствовать и 1.
будет заменен 01.
на в начале строки.
С awk
:
Опираясь на частичный awk
код в вопросе ...
Это, как указано, напечатает второй символ каждой строки ввода:
$ awk '{ print substr($0, 2, 1) }' file.txt
Мы можем использовать тот факт, что substr($0, 2, 1)
возвращает второй символ и использовать его в качестве условия:
$ awk 'substr($0, 2, 1) == "." { ... }' file.txt
То, что входит в это, { ... }
является кодом, который добавляет $0
, который является содержанием текущей строки, с нулем, если предыдущее условие истинно:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt
Тогда нам просто нужно убедиться, что все строки напечатаны:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt
substr($0, 2, 1) == "."
Конечно, условие может быть также изменено на регулярное выражение (мы используем точно такое же выражение, как и в sed
решении):
$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt
Некоторые люди, которые думают, что «короче, всегда лучше», написали бы это как
$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt
(и , вероятно , также удалить большинство пространства: awk '/^.\./{$0="0"$0}1' file.txt
)
sed 's/^.\./0&/' file.txt
. Я думаю, вы должны поставить это в начале этого ответа. Тем не менее +1.С помощью sed:
Шаблон
/^.\./
ищет любой символ и буквальную точку в начале строки^
, и, если они совпадают,s
замените начало строки на ноль, эффективно добавляя ноль к началу.Выражение sed
s/.\{0\}/0/
несколько странно, оно соответствует нулю или большему количеству копий чего-либо и заменяется на ноль. Шаблон, конечно, будет совпадать в каждой позиции строки, но поскольку онs///
заменяет только первое соответствие, он работает так, как вы предполагали. Хотя странный способ сделать это.Или с awk, аналогичное регулярное выражение будет работать, чтобы соответствовать строке, но мы можем использовать
substr
:Сначала мы проверяем, является ли второй символ точкой, а затем добавляем ноль в начало строки, если это так. Последний вызывает действие по умолчанию печати строки после любых изменений.
источник
Вы сказали awk и sed, но похоже, что вы пытаетесь отформатировать дату, и для этого я бы использовал
date
команду. Например:будет выводить
Команда
sed
в середине меняет точки на косые черты для ввода вdate -d
. Параметры формата позволяют выводить данные практически в любом формате. В%m
частности, это будет нулевое заполнение месяца, что, как кажется, вы пытаетесь сделать.Как указывает Кусалананда:
Еще более компактный (GNU date и Bash):
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
источник
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
s|\.|/|g
. В противном случае, как отмечено выше: хороший улов, +1Стратегия, отличная от представленной в других ответах: вы можете использовать «.» в качестве разделителя полей.
Вы можете сыграть в гольф, чтобы:
Для sed есть более короткая команда, представленная в другом (отличном) ответе.
источник
awk -F. '{print ($1<10?0$0:$0)}' file
С помощью sed это может быть
Это будет использоваться
^
для привязки к началу строки, затем захвата любого отдельного символа в группе, затем литерала.
, затем чего-либо еще. Если мы совпадаем с тем, что печатаем a0
, то наша первая группа захвата (символ в начале строки), затем a.
наша вторая группа захвата (остальная часть строки)источник
&
твой друг. Смотрите пример Кусалананды.sed
которая может быть полезна в других ситуациях, а не только в этой конкретной проблеме