Я пытаюсь использовать find, чтобы вывести список каталогов с определенным файлом внутри, но у моих каталогов есть пробелы, поэтому я не нашел решения.
4 ответа
Предполагая, что я действительно понимаю ваш вопрос, вы пробовали:
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
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, очищено на основе данных от Денниса Уильямсона
Это из файла Fedora .bashrc:
ff () {
find . -name "*$@*" -print;
}
Добавьте это в ваш .bashrc
и затем переинициализируйте вашу оболочку bash
Теперь вы можете использовать ff <whatever > \ <whatever>
\
Является escape-последовательностью для экранирования специальных символов.
zsh
не моя любимая оболочка, но для этой задачи ее ** - функция непобедима:
zsh -c "'ls **/'the file name'"
Или даже:
zsh -c "ls **/*'file name'"