Я хочу найти файл, а затем ввести каталог, содержащий его. Я пытался, find /media/storage -name "Fedora" | xargs cd
но, конечно, я is not a directory
ошибка.
Как мне ввести его родительский каталог с помощью однострочной команды?
shell
find
xargs
cd-command
Хрвое Т
источник
источник
shopt -s globstar
вы могли быcd /media/storage/**/Fedora
, но это не останавливает оценку глобуса при первом совпадении (так что это медленнее, чем решение SteelDriver. Для интерактивного использования я обычно использую мышь и копирую / вставляю имя каталога, (и alt + backspace по мере необходимости, чтобы убрать задние компоненты пути, которые я не хотел), но если вы будете делать это много, я думаю, что стоит сделать функцию оболочки.xargs cd
не может работать.cd
может работать только как встроенная оболочка, потому что она должна изменять контекст самой оболочки. Нет никакого способа, которымxargs
дочерний процесс может сделать это. IDK, если это то, что вы имели в виду под «конечно», или если путь, которыйfind
печатается, содержит пробелы, разделенные xargs, поскольку вы не использовали,-d \n
или что-то еще. Илиfind -exec {} \;
.cd
.cd
это встроенный bash, если быcd
это была отдельная команда, то он изменил бы (свой собственный) dir, а затем завершил работу (вернул вас в оболочку, которая находится в том же состоянии, что и раньше, без изменения dir).Ответы:
По крайней мере, если у вас есть GNU
find
, вы можете использовать,-printf '%h'
чтобы получить каталогТак что вы могли бы сделать
Значение
-quit
должно предотвращать множественные аргументы, еслиcd
в случае совпадения более одного файла.источник
-quit
также не обязательно поддерживается. В NetBSD это называется-exit
, см. Unix.stackexchange.com/a/62883/117599Похоже на решение Steeldriver, но использует
-execdir
(если выfind
его поддерживаете, например, GNU или FreeBSDfind
) в сочетании сpwd
:-quit
является необязательным в том случае, если есть только один результат, и сканирование всего каталога не представляет проблемы. В NetBSD он есть,-exit
а в OpenBSD его нет.источник
\;
?-exec
это говоритfind
о конце параметров для выполнения команды. Но так как мы хотим вызватьpwd
без параметров здесь, мы ставим\;
сразу после него.find
реализации, которые поддерживают execdir, но нет-printf %h
? Кажется маловероятным для меня. К сожалению, POSIX не требует ни того, ни другого: /find
: freebsd.org/cgi/man.cgi?find%281%29 (только что подтвердил это при установке FreeBSD 11.)-quit
/-exit
вообще, хотя.Вы можете заставить find запускать новую оболочку в каталоге, который он находит.
после чего текущим каталогом будет файл с именем Fedora. ;)
Очевидно, что это делает только то, что вы хотите, если вы вводите команды в интерактивном режиме.
источник
С
zsh
:чтобы
cd
в каталог первого (в алфавитном порядке) , который содержит файл с именемFedora
.**
: любой уровень каталогов (по умолчанию скрытые каталоги опущены, используйтеD
спецификатор glob, чтобы включить их)[1]
: только первый:h
: head модификатор: возьми dirname.В отличие от этого
cd "$(find ...)"
, это также работает, если имя каталога заканчивается символом новой строки. Еще одним преимуществом является то, что вы получите сообщение об ошибке отсутствия совпадения, когда нет соответствующего каталога (в то время как в большинстве оболочекcd ""
ничего не делается молча).Недостатком является то, что он будет ползти,
/media/storage
прежде чем вернуться.источник
cd
с несколькими аргументами в любом случае просматривается только первый аргумент, поэтому онcd $(dirname /media/storage/**/Fedora)
будет работать (сshopt -s globstar
), если в пути нет пробелов. Для того, чтобы получить его цитировали правильно, я думаю, что массив Баша проще:target=(/media/storage/**/Fedora); cd "${target%/*}"
. Но в этот момент было бы быстрее использовать мышь для копирования / вставки результатов поиска, а не интерактивно.dirname
реализации не будут принимать более одного аргумента. Обратите внимание, что это не пробелы , это любой символ в настоящее время$IFS
(пробел, табуляция и новая строка по умолчанию) и символы подстановки. Обратите внимание , что лиbash
«scd
будет принимать более одного аргумента зависит от того, как он был составлен (CD_COMPLAINS
вconfig-top.h
). Можно представить, что в будущих версияхbash
также будет реализована функция двух аргументов, как в zsh."${target%*/}"
расширяется только до первого элемента массива (с/Fedora
удаленным). Я думаю, что версия полностью устойчива к любым возможным символам в пути.