Я пытаюсь использовать find, чтобы вывести список каталогов с определенным файлом внутри, но у моих каталогов есть пробелы, поэтому я не нашел решения.

4 ответа4

1

Предполагая, что я действительно понимаю ваш вопрос, вы пробовали:

find / -name "*what*" -exec dirname {} \;

Это работает для меня, даже если в моих каталогах есть пробелы:

root:~# find / -name "*what*" -exec dirname {} \;
/usr/share/man/id/man1
...
...
/usr/share/man/ja/man1
/usr/share/man/it/man1
/usr/share/man/man1
/usr/bin
/root/This is a Spaced Dir
0

POSIX диктует довольно слабую find (серьезно, у нее даже нет -print0). Аналогично, xargs не будет иметь опцию -0 , и IEEE 1003.1-2008 считает xargs -I {} расширением X/Open System Interface (которое объявляет строку, заменяемую аргументами, и преобразует xargs в использование символов новой строки для ввода разделители аргументов). Таким образом, предполагая, что вы действительно хотите что-то сделать с путевыми именами, отличными от их распечатки, и если вы можете использовать только базовый POSIX, вам нужно будет экранировать пробелы в строках, прежде чем передавать их в xargs, таким образом:

find /startingdir -name 'file name' -exec dirname {} \; | sed 's/ /\\ /g' | xargs command

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

sed -e 's/\\/\\\\/' -e 's/ /\\ /g' -e 's/"/\\"/g' -e "s/'/\\\\'/g"

(Обратите внимание на дополнительную обратную косую черту в двойных кавычках. Строки в одинарных кавычках используют обратную косую черту буквально, но строки в двойных кавычках будут интерпретировать обратную косую черту, поэтому ваша оболочка будет интерпретировать "\\\\" как \\ что нужно sed для литерала \ , а '\\\\' интерпретируется как \\\\ который нужен в буквальном \\ .) Это позволит избежать существующих обратных косых черт, а затем пробелов, двойных и одинарных кавычек.

Если вы можете использовать расширения X/Open System Interface, то первая версия (без кавычек или обратной косой черты) упрощается до:

find /startingdir -name 'file name' -exec dirname {} \; | xargs -I {} command {}

Если в именах каталогов есть кавычки и обратная косая черта, их все равно нужно будет экранировать, как указано выше (но без экранирования).

В любом случае, если у вас есть новые строки в именах каталогов, тогда у вас проблемы больше, чем я могу помочь.

Отредактировано, чтобы удалить версию bash, очищено на основе данных от Денниса Уильямсона

0

Это из файла Fedora .bashrc:

ff () {
       find . -name "*$@*" -print;
       }

Добавьте это в ваш .bashrc и затем переинициализируйте вашу оболочку bash

Теперь вы можете использовать ff <whatever > \ <whatever>

\ Является escape-последовательностью для экранирования специальных символов.

0

zsh не моя любимая оболочка, но для этой задачи ее ** - функция непобедима:

zsh -c "'ls **/'the file name'"

Или даже:

zsh -c "ls **/*'file name'"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .