SED приказал проверить ДАТА палиндромно - PullRequest
2 голосов
/ 13 февраля 2020

У меня есть файл с датами в формате MM / D / YYYY, который называется date.txt

02/02/2020
08/25/1998
03/02/2030
12/02/2021
06/19/1960
01/10/2010
03/07/2100 

Мне нужна однострочная команда SED для печати только палиндроми c. Например, 02.02.2020 - это палиндроми c, а 25.08.2020 - нет. Ожидаемый результат:

02/02/2020
03/02/2030
12/02/2021

То, что я делал до сих пор, это удаление / из формата даты. Как проверить, выводят ли одно и то же чтение от начала и до конца?

sed -E "s|([0-9]{2})/([0-9]{2})/([0-9]{4})|\3\2\1|" dates.txt

Вот что я получаю:

20200202
19982508
20300203
20210212
19601906
20101001
21000703

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Вы можете использовать обратную ссылку в сопоставлении с образцом:

sed -n '/\([0-9]\)\([0-9]\)\/\([0-9]\)\([0-9]\)\/\4\3\2\1/p'

Использование расширенного регулярного выражения и точек выглядит просто замечательно:

sed -rn '/(.)(.)\/(.)(.)\/\4\3\2\1/p'
sed -rn '\@(.)(.)/(.)(.)/\4\3\2\1@p'      # means the same
1 голос
/ 13 февраля 2020

Вы можете удалить любую строку, которая не соответствует шаблону d1d2/M1M2/M2M1d2d1. Чтобы проверить это, сопоставьте и запишите все цифры дня и месяца отдельно :

sed -E '/^([0-9])([0-9])\/([0-9])([0-9])\/\4\3\2\1$/!d' file > outfile

Или с помощью GNU sed:

sed -i -E '/^([0-9])([0-9])\/([0-9])([0-9])\/\4\3\2\1$/!d' file

^ обозначает начало строки и $ означает конец строки. !d в конце говорит sed «отбросить» строки, которые не следуют этому шаблону.

См. онлайн-демонстрацию .

В качестве альтернативы, когда у вас есть более сложные случаи, вы можете читать файл построчно, менять цифры в днях и месяцах, объединять их и сравнивать значение с частью года. При необходимости вы можете выполнить больше операций:

while IFS= read -r line; do
  p1="$(sed -En 's,([0-9])([0-9])/([0-9])([0-9])/.*,\4\3\2\1,p' <<< "$line")";
  p2="${line##*/}";
  if [[ "$p1" == "$p2" ]]; then
    echo "$line"
  fi
done < file > outfile

См. Онлайн-демонстрацию

Часть sed -En 's,([0-9])([0-9])/([0-9])([0-9])/.*,\4\3\2\1,p получает первые четыре цифры и переупорядочивает их. "${line##*/}" использует расширение параметра, чтобы удалить как можно больше символов с начала до последнего / (включая его).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...