регулярное выражение: совпадение двух / с конца строки [дубликат]

У меня есть файл с путями к файлам. Глубина каталогов бывает разной длины и имени пути. Я хотел бы сопоставить два каталога назад (два /) и удалить совпадение, создав новый файл с результатами.

например:

/dir1/dir2/dir3/dir4/dir5/dir6/dir7/output_job3344.xml
/dir1/dir2/dir3/dir4/dir5/otherfile.txt

результат будет:

/dir1/dir2/dir3/dir4/dir5/dir6/
/dir1/dir2/dir3/dir4/

Я пробовал что-то вроде этого:

awk -F'/*./.*$' '{print $0}' deep.list

, но это не сработало.

1
задан 1 September 2018 в 18:27
1 ответ

Ваша идея умна , но требует некоторых исправлений. Вот как вы, вероятно, имели в виду:

awk -F'[^/]*/[^/]*$' '{print $1}' deep.list

Объяснение:

Во-первых, вы, вероятно, неправильно написали . * как *. .

Затем * модификатор жадный , поэтому вам нужно следить, чтобы он не совпадал больше, чем вы предполагали! Решение простое, хотя и немного менее читаемое: используйте [^ /] * вместо . * . Таким образом, вы сопоставляете любые символы, кроме / .

Наконец, $ 0 представляет собой всю строку, которая ни в малейшей степени не была изменена путем указания специально созданного настраиваемого разделителя полей. В этом случае вы хотите вместо этого напечатать первое поле: $ 1 .


Здесь другой подход, нежели два ответа , связанных (скрытым) одним с использованием цикла:

awk -F/ '{for(i=1;i<=NF-2;i++){printf "%s/",$i}; print ""}' deep.list

Метод подстановки проще реализовать в Perl:

perl -lape 's"[^/]+/[^/]+$""' deep.list

или sed:

sed -E 's"[^/]+/[^/]+$""' deep.list
0
ответ дан 4 December 2019 в 03:45

Теги

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