Найдите файлы с тем же именем, что и каталог

Обычно я делаю то же самое с awk, но вот ряд текстовых инструментов для достижения того же результата:

$ echo "0000    $s" | sort -k2 - infile | grep -B1 "$s" | head -1 | cut -d" " -f1
0298
5
08.04.2020, 14:06
3 ответа

Так как обычно каталогов меньше, чем файлов, давайте найдем все каталоги, а затем проверим, содержат ли они требуемое имя файла.

find. -type d -exec sh -c '
    for dirpath do
        filepath="$dirpath/${dirpath##*/}"
        [ -f "$filepath" ] && printf "%s\n" "$filepath"
    done' sh {} +

Это напечатает пути ко всем обычным файлам (и символические ссылки на обычные файлы ), расположенные в каталоге с тем же именем, что и файл.

Тест выполняется в коротком сценарии -строки sh -c, который получает в качестве аргументов несколько путей к каталогам. Он выполняет итерацию по каждому пути к каталогу и создает путь к файлу с именем, которое мы ищем. ${dirpath##*/}в коде можно заменить на $(basename "$dirpath").

Для данного примера структуры каталогов это выведет

./Example1/Example1
./Example2/Example2

Чтобы просто проверить любое имя , а не только обычные файлы, измените тест -fна тест -e.

8
28.04.2021, 23:18

Используйтеfind -exec:

find. -type f \
  -exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
  -print

-printбудет выполняться, только если результат [... ]внутри -exec sh -c '...'истинен.

Выход:

./Example1/Example1
./Example2/Example2
5
28.04.2021, 23:18

Вы можете легко сопоставить имена файлов, которые имеют то же имя, что и содержащий каталог, с регулярным выражением, используя обратную ссылку. Это имена файлов вида what/ever/something/something, где две части somethingидентичны и не содержат косой черты. В синтаксисе регулярных выражений BRE [^/]*соответствует любой строке, не содержащей косой черты, \(/[^/]*\)соответствует косой черте, за которой следует любое количество символов, отличных от -, и делает все это группой, а \1соответствует тот же текст, который соответствует первой группе, поэтому \(/[^/]*\)\1соответствует двум сегментам пути с одинаковыми именами. Добавьте .*в начале, чтобы соответствовать предыдущим компонентам каталога.

С помощью GNU find, FreeBSD find,macOS find или любой другой find, который поддерживает-regex:

find. -regex '.*\(/[^/]*\)\1'
19
28.04.2021, 23:18

Теги

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