Saya ingin mencari file dan kemudian memasukkan direktori yang berisi itu. Saya mencoba find /media/storage -name "Fedora" | xargs cd
tetapi tentu saja, saya is not a directory
kesalahannya.
Bagaimana cara memasukkan direktori induknya dengan perintah satu baris?
shell
find
xargs
cd-command
Hrvoje T
sumber
sumber
shopt -s globstar
, Anda bisacd /media/storage/**/Fedora
, tetapi itu tidak berhenti mengevaluasi glob pada pertandingan pertama (jadi itu lebih lambat daripada solusi steeldriver. Untuk penggunaan interaktif, apa yang biasanya saya lakukan adalah meraih mouse dan menyalin / menempelkan nama direktori, (dan alt + backspace yang diperlukan untuk menanggalkan komponen path trailing yang tidak saya inginkan), tetapi jika Anda sering melakukan ini, saya rasa fungsi shell bisa bernilai.xargs cd
tidak mungkin bekerja.cd
hanya dapat berfungsi sebagai shell builtin, karena harus memodifikasi konteks shell itu sendiri. Tidak mungkinxargs
proses anak dapat melakukannya. IDK jika itu yang Anda maksud dengan "tentu saja", atau jika jalur yangfind
mencetak berisi spasi, yang dipisahkan oleh xargs karena Anda tidak menggunakan-d \n
atau apa pun. Ataufind -exec {} \;
.cd
seperti itu.cd
adalah sebuah bash yang dibangun, jikacd
merupakan perintah yang terpisah, maka itu akan mengubah dir (miliknya), dan kemudian berhenti (mengembalikan Anda ke shell, yang berada dalam keadaan yang sama seperti sebelumnya, tidak ada perubahan dir).Jawaban:
Setidaknya jika Anda memiliki GNU
find
, Anda dapat menggunakan-printf '%h'
untuk mendapatkan direktoriJadi mungkin Anda bisa melakukannya
The
-quit
seharusnya mencegah beberapa argumen untukcd
dalam kasus lebih dari satu file cocok.sumber
-quit
juga belum tentu didukung. Di NetBSD namanya-exit
, lihat unix.stackexchange.com/a/62883/117599Mirip dengan solusi steeldriver tetapi menggunakan
-execdir
(jika Andafind
mendukungnya, seperti GNU atau FreeBSDfind
) dalam kombinasi denganpwd
:-quit
bersifat opsional jika hanya ada satu hasil dan merayapi seluruh direktori tidak ada masalah. Di NetBSD itu-exit
dan di OpenBSD tidak ada.sumber
\;
?-exec
itu menceritakanfind
tentang akhir parameter untuk perintah untuk dieksekusi. Tetapi karena kita ingin memanggilpwd
tanpa parameter di sini, kita meletakkannya\;
tepat setelahnya.find
implementasi yang mendukung execdir tetapi tidak-printf %h
? Sepertinya tidak bagi saya. Sayangnya tidak ada yang diminta oleh POSIX: /find
: freebsd.org/cgi/man.cgi?find%281%29 (Baru saja mengonfirmasikannya pada instalasi FreeBSD 11).-quit
/-exit
sama sekali.Anda dapat membuat find menjalankan shell baru di direktori yang ditemukannya.
, setelah itu direktori saat ini akan menjadi orang yang memiliki file bernama Fedora di dalamnya. ;)
Jelas ini hanya melakukan sesuatu yang menyerupai apa yang Anda inginkan jika Anda mengetik perintah secara interaktif.
sumber
Dengan
zsh
:untuk
cd
masuk ke direktori pertama (dalam urutan abjad) yang berisi file bernamaFedora
.**
: semua tingkat direktori (direktori tersembunyi dihilangkan secara default, gunakanD
kualifikasi glob untuk memasukkannya)[1]
: hanya yang pertama:h
: head modifier: ambil dirname.Berlawanan dengan
cd "$(find ...)"
itu, ia juga berfungsi jika nama direktori berakhir dengan karakter baris baru. Keuntungan lain adalah bahwa Anda akan mendapatkan pesan kesalahan tidak cocok ketika tidak ada direktori yang cocok (sementara di sebagian besar shellcd ""
tidak akan melakukan apa pun secara diam-diam).Kekurangannya adalah ia akan merayapi keseluruhan
/media/storage
sebelum kembali.sumber
cd
dengan beberapa args hanya melihat argumen pertama, jadicd $(dirname /media/storage/**/Fedora)
akan bekerja (denganshopt -s globstar
) jika tidak ada spasi di path. Untuk mendapatkannya dikutip benar, saya pikir array bash adalah yang paling mudah:target=(/media/storage/**/Fedora); cd "${target%/*}"
. Tetapi pada saat itu akan lebih cepat untuk menggunakan mouse untuk menyalin / menempelkan output yang ditemukan alih-alih menghasilkan secara interaktif.dirname
implementasi tidak akan menerima lebih dari satu argumen. Perhatikan bahwa ini bukan spasi , karakter apa pun yang ada saat ini$IFS
(spasi, tab, dan baris baru secara default) dan karakter wildcard. Perhatikan bahwa apakahbash
'scd
akan menerima lebih dari satu argumen tergantung pada bagaimana itu dikompilasi (CD_COMPLAINS
diconfig-top.h
). Orang dapat membayangkan bahwa versi masa depanbash
juga pada akhirnya akan mengimplementasikan fitur dua arg seperti di zsh."${target%*/}"
memperluas hanya elemen array pertama (dengan/Fedora
strip). Saya pikir versi itu sepenuhnya kuat terhadap karakter yang mungkin ada di pathname.