Quero encontrar um arquivo e, em seguida, digite o diretório que o contém. Eu tentei, find /media/storage -name "Fedora" | xargs cd
mas é claro, eu o is not a directory
erro.
Como insiro seu diretório pai com um comando de uma linha?
shell
find
xargs
cd-command
Hrvoje T
fonte
fonte
shopt -s globstar
, você poderiacd /media/storage/**/Fedora
, mas isso não para de avaliar o globo na primeira partida (portanto, é mais lento que a solução da steeldriver. Para uso interativo, o que eu normalmente faria é procurar o mouse e copiar / colar o nome do diretório, (e alt + backspace conforme necessário para retirar componentes de caminho de fuga que eu não queria), mas se você fizer muito isso eu acho uma função shell pode valer tomada.xargs cd
não pode funcionar.cd
só pode funcionar como um shell embutido, porque precisa modificar o contexto do próprio shell. Não há como umxargs
processo filho fazer isso. IDK, se é isso que você quis dizer com "é claro", ou se o caminho quefind
imprime contém espaços, que são divididos por xargs, pois você não usou-d \n
nada. Orfind -exec {} \;
.cd
assim.cd
é um bash embutido, secd
fosse um comando separado, ele mudará o (próprio) dir e, em seguida, sairá (retornando você ao shell, que está no mesmo estado de antes, sem alteração de dir).Respostas:
Pelo menos se você possui o GNU
find
, pode usar-printf '%h'
para obter o diretórioEntão você provavelmente poderia fazer
Isso
-quit
deve impedir vários argumentoscd
no caso de mais de um arquivo corresponder.fonte
-quit
também não é necessariamente suportado. No NetBSD é chamado-exit
, consulte unix.stackexchange.com/a/62883/117599Semelhante à solução da steeldriver, mas usando
-execdir
(se você afind
suportar, como GNU ou FreeBSDfind
) em combinação compwd
:-quit
é opcional caso apenas haja um único resultado e o rastreamento de todo o diretório não seja um problema. No NetBSD é-exit
e no OpenBSD não existe.fonte
\;
?-exec
ele, falafind
sobre o fim dos parâmetros para o comando executar. Mas como queremos chamarpwd
sem parâmetros aqui, colocamos\;
logo depois.find
implementações que suportam execdir, mas não-printf %h
? Parece improvável para mim. Infelizmente, nenhum dos dois é exigido pelo POSIX: /find
: freebsd.org/cgi/man.cgi?find%281%29 (Acabei de confirmar em uma instalação do FreeBSD 11).-quit
/ de-exit
todo.Você pode fazer com que o find execute um novo shell no diretório que ele encontra.
, após o qual o diretório atual será aquele que possui um arquivo chamado Fedora. ;)
Obviamente, isso só faz algo parecido com o que você deseja se estiver digitando comandos interativamente.
fonte
Com
zsh
:para
cd
o primeiro diretório (em ordem alfabética) que contém um arquivo chamadoFedora
.**
: qualquer nível de diretório (os diretórios ocultos são omitidos por padrão, use oD
qualificador glob para incluí-los)[1]
: apenas o primeiro:h
: head modifier: leva o nome do diretórioAo contrário
cd "$(find ...)"
, também funciona se o nome do diretório terminar em um caractere de nova linha. Outra vantagem é que você recebe uma mensagem de erro de não correspondência quando não há diretório correspondente (enquanto na maioria dos shellscd ""
não faria nada silenciosamente).Uma desvantagem é que ele rastrearia todo
/media/storage
antes de retornar.fonte
cd
com vários argumentos apenas olha para o primeiro argumento de qualquer maneira, entãocd $(dirname /media/storage/**/Fedora)
funcionaria (comshopt -s globstar
) se não houver espaços no caminho. Para obtê-lo citado corretamente, eu acho que uma matriz bash é mais fácil:target=(/media/storage/**/Fedora); cd "${target%/*}"
. Mas, nesse ponto, teria sido mais rápido usar o mouse para copiar / colar a saída de localização, em vez de criar a interatividade.dirname
implementações não aceitam mais de um argumento. Observe que não são espaços , é qualquer caractere atualmente em$IFS
(espaço, tab e nova linha por padrão) e caracteres curinga. Observe quebash
acd
aceitação de mais de um argumento depende de como ele foi compilado (CD_COMPLAINS
emconfig-top.h
). Pode-se imaginar que versões futurasbash
também implementarão o recurso de dois argumentos, como no zsh."${target%*/}"
expande apenas para o primeiro elemento do array (com o/Fedora
stripped). Eu acho que essa versão é totalmente robusta contra quaisquer caracteres possíveis no nome do caminho.