
Я пытаюсь добавить 0 в начало, ЕСЛИ на втором месте этой строки стоит "." Я не смог объединить эти два символа;
awk '{ print substr( $0, 2, 1 ) }' file.txt
показывая второй символ
sed -ie "s/.\{0\}/0/" file.txt
добавляя ноль в начало.
Должно быть «если второй символ — точка».
пример файла:
1.02.2017 23:40:00
10.02.2017 23:40:00
финал:
01.02.2017 23:40:00
10.02.2017 23:40:00
решение1
Мы можем использовать любой из вариантов 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
)
решение2
С sed:
sed -e "/^.\./s/^/0/" file.txt
Шаблон /^.\./
ищет любой символ и буквальную точку в начале строки ^
, и если они совпадают, s
заменяет начало строки нулем, фактически добавляя ноль к началу.
Экспресс-команда sed s/.\{0\}/0/
немного странная, она сопоставляет ноль или более копий чего угодно и заменяет на ноль. Шаблон, конечно, будет совпадать в каждой позиции строки, но поскольку s///
заменяет только первое совпадение, он работает так, как вы и предполагали. Хотя это и странный способ сделать это.
Или с помощью awk для сопоставления строки будет работать похожее регулярное выражение, но мы можем использовать substr
:
awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt
Сначала мы проверяем, является ли второй символ точкой, затем добавляем ноль в начало строки, если это так. Последний вызывает действие по умолчанию — печать строки после любых изменений.
решение3
Вы сказали awk и sed, но похоже, что вы пытаетесь отформатировать дату, и для этого я бы использовал команду date
. Например:
echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d
выведет
01.02.2017 23:40:00
Команда sed
в середине меняет точки на косые черты для ввода в date -d
. Параметры формата позволяют выводить данные практически в любом желаемом формате. %m
В частности, команда дополнит месяц нулями, что, похоже, вы и пытаетесь сделать.
Как отмечает Кусалананда:
Еще компактнее (GNU date и Bash):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
решение4
С sed это может быть
sed 's/^\(.\)\.\(.*\)/0\1.\2/'
Это будет использоваться ^
для привязки к началу строки, затем захват любого отдельного символа в группе, за которым следует литерал .
, затем что-либо еще. Если мы сопоставляем это, мы печатаем 0
, затем нашу первую группу захвата (символ в начале строки), затем a , .
затем нашу вторую группу захвата (остальная часть строки)