Chcę znaleźć plik, a następnie wejść do katalogu zawierającego go. Próbowałem, find /media/storage -name "Fedora" | xargs cd
ale oczywiście is not a directory
popełniłem błąd.
Jak wprowadzić katalog nadrzędny za pomocą polecenia w jednym wierszu?
shell
find
xargs
cd-command
Hrvoje T.
źródło
źródło
shopt -s globstar
, możeszcd /media/storage/**/Fedora
, ale to nie przestaje oceniać globu przy pierwszym dopasowaniu (więc jest wolniejsze niż rozwiązanie steeldriver. W przypadku użycia interaktywnego zwykle sięgam po mysz i kopiuję / wklejam nazwę katalogu, (i alt + backspace w razie potrzeby, aby usunąć komponenty ścieżki końcowej, których nie chciałem), ale jeśli robisz to dużo, wydaje mi się, że warto zastosować funkcję powłoki.xargs cd
prawdopodobnie nie może działać.cd
może działać tylko jako wbudowana powłoka, ponieważ musi modyfikować kontekst samej powłoki. Nie ma możliwości, abyxargs
proces potomny mógł to zrobić. IDK, jeśli to właśnie rozumiesz przez „oczywiście”, lub jeślifind
drukowana ścieżka zawiera spacje, które są podzielone przez xargs, ponieważ nie używałeś-d \n
lub nic. Lubfind -exec {} \;
.cd
.cd
to wbudowane bash, gdybycd
były osobnym poleceniem, to zmieniłoby (własny) katalog, a następnie zakończyłoby (powrót do powłoki, czyli w takim samym stanie jak poprzednio, bez zmiany katalogu).Odpowiedzi:
Przynajmniej jeśli masz GNU
find
, możesz użyć,-printf '%h'
aby uzyskać katalogWięc prawdopodobnie możesz to zrobić
-quit
Powinno zapobiec wielu argumentów, abycd
w przypadku, gdy więcej niż jeden plik meczów.źródło
-quit
niekoniecznie jest również obsługiwany. W NetBSD nazywa się to-exit
, patrz unix.stackexchange.com/a/62883/117599Podobne do rozwiązania steeldriver, ale przy użyciu
-execdir
(jeślifind
obsługuje, np. GNU lub FreeBSDfind
) w połączeniu zpwd
:-quit
jest opcjonalny w przypadku, gdy tylko jeden wynik jest tylko jeden i przy przeszukiwaniu całego katalogu nie ma problemu. Na NetBSD jest,-exit
a na OpenBSD nie istnieje.źródło
\;
?-exec
, mówifind
o końcu parametrów do wykonania polecenia. Ale ponieważ chcemypwd
tutaj dzwonić bez parametrów, umieszczamy\;
zaraz po nim.find
implementacje, które obsługują execdir, ale nie-printf %h
? Wydaje mi się to mało prawdopodobne. Niestety, żadne z nich nie jest wymagane przez POSIX: /find
: freebsd.org/cgi/man.cgi?find%281%29 (Właśnie to potwierdziłem w instalacji FreeBSD 11).-quit
/-exit
wcale.Możesz sprawić, aby find uruchomił nową powłokę w znalezionym katalogu.
, po którym bieżącym katalogiem będzie ten, w którym znajduje się plik o nazwie Fedora. ;)
Oczywiście robi to tylko coś, co chcesz, jeśli wpisujesz polecenia interaktywnie.
źródło
Z
zsh
:do
cd
pierwszego (w kolejności alfabetycznej) katalogu zawierającego plik o nazwieFedora
.**
: dowolny poziom katalogów (ukryte katalogi są domyślnie pomijane, użyjD
kwalifikatora glob, aby je uwzględnić)[1]
: tylko pierwszy:h
: modyfikator głowy : weź nazwę katalogu.W przeciwieństwie do
cd "$(find ...)"
tego działa również, jeśli nazwa katalogu kończy się znakiem nowej linii. Kolejną zaletą jest to, że chcesz dostać żadnego meczu komunikat o błędzie, gdy nie ma katalogu dopasowanie (podczas gdy w większości powłokcd ""
zrobi nic, cicho).Wadą jest to, że czołgałby się cały
/media/storage
przed powrotem.źródło
cd
z wieloma argumentami i tak patrzy tylko na pierwszy argument, więccd $(dirname /media/storage/**/Fedora)
działałoby (zshopt -s globstar
), jeśli na ścieżce nie ma spacji. Aby dostać cytowany poprawnie, myślę, że najłatwiej jest tablica bash:target=(/media/storage/**/Fedora); cd "${target%/*}"
. Ale w tym momencie szybsze byłoby użycie myszy do kopiowania / wklejania wyników wyszukiwania zamiast interaktywnego wymyślania tego.dirname
implementacji nie akceptuje więcej niż jednego argumentu. Pamiętaj, że nie jest to spacja , to obecnie dowolny znak$IFS
(domyślnie spacja, tabulator i nowa linia) oraz znaki wieloznaczne. Należy pamiętać, że czybash
jestcd
przyjmie więcej niż jeden argument zależy od tego jak został skompilowany (CD_COMPLAINS
wconfig-top.h
). Można sobie wyobrazić, że przyszłe wersjebash
będą również ostatecznie implementować funkcję dwóch argumentów, tak jak w Zsh."${target%*/}"
rozwija się tylko do pierwszego elementu tablicy (z/Fedora
pasmem). Myślę, że ta wersja jest w pełni odporna na wszelkie możliwe znaki w nazwie ścieżki.