На этот вопрос уже есть ответ здесь:
У меня есть файл с путями к файлам. Глубина каталогов бывает разной длины и имени пути. Я хотел бы сопоставить два каталога назад (два /) и удалить совпадение, создав новый файл с результатами.
например:
/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
, но это не сработало.
Ваша идея умна , но требует некоторых исправлений. Вот как вы, вероятно, имели в виду:
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