awk sed якщо заява


9

Я намагаюся додати 0 до початку, якщо є "". на 2-му символі цього рядка. Я не міг поєднати цих двох;

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

Відповіді:


12

Ми можемо використати будь- яку проблему 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)


1
+1 Ваш останній приклад AWK або ваш приклад sed - це правильні способи зробити це. Зауважте, для наочності, що це було б лише те чи інше.
Призупинено до подальшого повідомлення.

На моєму погляді , «правильний» підхід (яка не робить скрипку з пробілами і що більш легкий вага в будь-якому випадку) є остаточним варіантом, sed 's/^.\./0&/' file.txt. Я думаю, ви повинні поставити це на початку цієї відповіді. Все-таки +1.
Wildcard

1
@Wildcard Ми прагнемо догодити.
Кусалаланда

5

З sed:

sed -e "/^.\./s/^/0/" file.txt 

Шаблон /^.\./шукає будь-який символ і буквальну крапку на початку рядка ^, і якщо це збігається, sзамініть цей початок рядка з нулем, фактично додавши нуль до початку.

Sed expressoin s/.\{0\}/0/дещо дивний, він відповідає нулю або більше копій будь-чого і замінює нуль. Зразок, звичайно, збігатиметься в кожному положенні рядка, але оскільки s///замінює лише перший збіг, він працює так, як ви задумали. Хоч химерний спосіб це зробити.


Або з awk, аналогічний регулярний вираз буде працювати у відповідності з рядком, але ми можемо використовувати substr:

awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

Ми спочатку перевіряємо, чи є другий символ крапкою, а потім додаємо нуль до передньої частини рядка, якщо так. Останній викликає дію за замовчуванням друку рядка після будь-яких модифікацій.


4

Ви сказали awk and 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 та Bash): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'


2
Приємний улов! Ще компактніше (дата GNU та Bash):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
Kusalananda

Всякий раз , коли у мене є слеші в моїх моделях, але ніяких труб: s|\.|/|g. Інакше, як зазначалося вище: Хороший улов, +1
Алекс Страгіс

2

Інша стратегія, ніж представлена ​​в інших відповідях: "Ви можете використовувати". як роздільник поля.

awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt

Можна взяти гольф для цього:

awk -F. '$1<10{printf "0"}1' /tmp/in.txt

Для sed існує коротша команда, представлена ​​в іншій (чудовій) відповіді.


1
Альтернатива: awk -F. '{print ($1<10?0$0:$0)}' file
Джордж Васильоу

1

З sed це могло бути

sed 's/^\(.\)\.\(.*\)/0\1.\2/'

Це використовуватиметься ^для прив’язки до початку рядка, а потім захоплення будь-якого окремого символу в групі, за яким слід буквальне ., а потім все інше. Якщо ми збігаємося з тим, що друкуємо a 0, то наша перша група захоплення (символ на початку рядка), потім .друга наша група захоплення (решта рядка)


Зовсім не потрібно робити щось із цього захоплення. &твій друг. Див. Приклад кусалананди.
Призупинено до подальшого повідомлення.

@DennisWilliamson не потрібен, але, зважаючи на інші приклади, це вже показує ще одну особливість, sedяка може бути корисною в інших ситуаціях, а не тільки для цієї конкретної проблеми
Ерік Реноф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.