Каталог пропадает при передаче базового имени из имени каталога

Учитывая структуру папок

/recipes/foo/.env
/recipes/bar/.env

Выполнение следующей команды:

find ./recipes -type f -name '.env' -print0 | xargs -0 dirname | xargs -0 basename

Output:
foo

Обрезка команды до:

find ./recipes -type f -name '.env' -print0 | xargs -0 dirname

Output:
./recipes/bar
./recipes/foo

Поэтому по какой-то причине передача имени каталога в базовое имя приводит к потере некоторых найденных каталогов.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь есть 2 проблемы:

  1. Опция -0 для xargs указывает, что входы разделены NUL, а не выходы. Чтобы передать вывод xargs -0 dirname в xargs -0 something, вы должны использовать опцию -z для dirname, если она поддерживается (это не POSIX). В противном случае его вывод разделяется символом новой строки.

  2. basename по умолчанию не поддерживает несколько аргументов. Если ваш поддерживает это (это не POSIX), вы можете попробовать -a или --multiple.

    find ./recipes -type f -name '.env' -print0 |
      xargs -0 dirname -z | xargs -0 basename -a
    

    В противном случае используйте опцию -n1 для xargs:

    find ./recipes -type f -name '.env' -print0 |
      xargs -0 dirname -z | xargs -0 -n1 basename
    

Примечание: поскольку ваш find, очевидно, GNU find, вы можете пропустить dirname с помощью:

find ./recipes -type f -name '.env' -printf '%h\0' | xargs -0 basename -a

Примечание: вы также можете использовать только find и любую оболочку POSIX:

find ./recipes -type f -name '.env' -exec sh -c '
d = "${1%/*}"; printf "%s\n" "${d##*/}"' _ {} \;

Примечание. Если, как в примере, который вы показываете, глубина файлов .env равна 2, вам не нужны find, xargs, dirname или basename. Вашей (POSIX) оболочки достаточно (плюс утилита printf, если она еще не встроена в вашу оболочку):

for f in recipes/*; do [ -f "$f/.env" ] && printf '%s\n' "${f##*/}"; done

или find ... -print0 | awk -vRS='\0' -F/ '{print $(NF-1)}'

dave_thompson_085 17.07.2024 08:08

@dave_thompson_085. Да, но поскольку RS='\0' не является POSIX, для этого требуется GNU awk или другой awk, поддерживающий его.

Renaud Pacalet 17.07.2024 08:14
-print0 также не является POSIX, и если вы опустите это (и не будете использовать новую строку в своих именах путей, что делает только сумасшедший), POSIX awk \n будет работать
dave_thompson_085 19.07.2024 07:45

@dave_thompson_085 Я полностью согласен с тобой, Дэйв, и поскольку find ОП, очевидно, является GNU find, мы можем предположить, что их awk тоже GNU. Мы также можем предположить, что в их путях нет символов новой строки. Моя личная позиция (можете не соглашаться) заключается в том, что не зная, кто будет читать эти вопросы и ответы и что с ними будут делать, я предпочитаю пытаться предложить решения, которые не смогут сломаться, даже с малой вероятностью. И я не говорю, что мне всегда это удается. Просто пытаюсь. Итак, если бы я добавил ваше решение на основе awk к своему (и без того слишком длинному) ответу, я бы также добавил только GNU.

Renaud Pacalet 19.07.2024 08:26

Другие вопросы по теме