Обычно я делаю то же самое с awk
, но вот ряд текстовых инструментов для достижения того же результата:
$ echo "0000 $s" | sort -k2 - infile | grep -B1 "$s" | head -1 | cut -d" " -f1
0298
Так как обычно каталогов меньше, чем файлов, давайте найдем все каталоги, а затем проверим, содержат ли они требуемое имя файла.
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
.
Используйтеfind -exec
:
find. -type f \
-exec sh -c '[ "$(basename "$1")" = "$(basename "$(dirname "$1")")" ]' find-sh {} \; \
-print
-print
будет выполняться, только если результат [... ]
внутри -exec sh -c '...'
истинен.
Выход:
./Example1/Example1
./Example2/Example2
Вы можете легко сопоставить имена файлов, которые имеют то же имя, что и содержащий каталог, с регулярным выражением, используя обратную ссылку. Это имена файлов вида what/ever/something/something
, где две части something
идентичны и не содержат косой черты. В синтаксисе регулярных выражений BRE [^/]*
соответствует любой строке, не содержащей косой черты, \(/[^/]*\)
соответствует косой черте, за которой следует любое количество символов, отличных от -, и делает все это группой, а \1
соответствует тот же текст, который соответствует первой группе, поэтому \(/[^/]*\)\1
соответствует двум сегментам пути с одинаковыми именами. Добавьте .*
в начале, чтобы соответствовать предыдущим компонентам каталога.
С помощью GNU find, FreeBSD find,macOS find или любой другой find
, который поддерживает-regex
:
find. -regex '.*\(/[^/]*\)\1'