Jawaban:
Anda dapat menentukan garis miring di akhir agar hanya cocok dengan direktori:
for d in */ ; do
echo "$d"
done
[[ -L $d ]]
apakah $ d adalah tautan simbolik.
set -P
hanya memengaruhi perintah yang mengubah direktori. sprunge.us/TNac
[[ -L "$f" ]]
tidak akan mengecualikan symlink dalam hal ini dengan */
, Anda harus menghapus garis miring dengan [[ -L "${f%/}" ]]
(lihat Tes untuk tautan dengan garis miring )
Anda dapat menguji dengan -d
:
for f in *; do
if [ -d "$f" ]; then
# $f is a directory
fi
done
Ini adalah salah satu operator pengujian file .
if [[ -d "$f" && ! -L "$f" ]]
akan mengecualikan symlink
if [[ "$f" = "*" ]]; then continue; fi
Waspadalah bahwa solusi choroba, meskipun elegan, dapat menimbulkan perilaku yang tidak terduga jika tidak ada direktori yang tersedia dalam direktori saat ini. Dalam keadaan ini, alih-alih melewatkan for
loop, bash akan menjalankan loop tepat sekali di mana d
sama dengan */
:
#!/usr/bin/env bash
for d in */; do
# Will print */ if no directories are available
echo $d
done
Saya sarankan menggunakan yang berikut ini untuk melindungi dari kasus ini:
#!/usr/bin/env bash
for f in *; do
if [ -d ${f} ]; then
# Will not run if no directories are available
echo $f
fi
done
Kode ini akan mengulang semua file dalam direktori saat ini, memeriksa apakah f
direktori, lalu menggema f
jika kondisinya kembali benar. Jika f
sama dengan */
, echo $f
tidak akan dieksekusi.
shopt -s nullglob
.
Jika Anda perlu memilih file yang lebih spesifik daripada hanya menggunakan direktori find
dan meneruskannya ke while read
:
shopt -s dotglob
find * -prune -type d | while IFS= read -r d; do
echo "$d"
done
Gunakan shopt -u dotglob
untuk mengecualikan direktori tersembunyi (atau setopt dotglob
/ unsetopt dotglob
di zsh).
IFS=
untuk menghindari pemisahan nama file yang mengandung salah satu $IFS
, misalnya:'a b'
lihat jawaban AsymLabs di bawah ini untuk find
opsi lebih lanjut
sunting:
Jika Anda perlu membuat nilai keluar dari dalam loop sementara, Anda dapat menghindari subkulit tambahan dengan trik ini:
while IFS= read -r d; do
if [ "$d" == "something" ]; then exit 1; fi
done < <(find * -prune -type d)
Anda dapat menggunakan bash murni untuk itu, tetapi lebih baik menggunakan find:
find . -maxdepth 1 -type d -exec echo {} \;
(temukan tambahan akan termasuk direktori tersembunyi)
shopt -s dotglob
untuk bash
memasukkan direktori tersembunyi. Anda juga akan termasuk .
. Perhatikan juga bahwa -maxdepth
ini bukan opsi standar -prune
.
dotglob
pilihan adalah menarik tapi dotglob
hanya berlaku untuk penggunaan *
. find .
akan selalu menyertakan direktori tersembunyi (dan direktori saat ini juga)
Ini dilakukan untuk menemukan direktori yang terlihat dan tersembunyi di dalam direktori kerja saat ini, tidak termasuk direktori root:
untuk hanya mengulang direktori:
find -path './*' -prune -type d
untuk memasukkan symlink dalam hasil:
find -L -path './*' -prune -type d
untuk melakukan sesuatu pada setiap direktori (tidak termasuk symlinks):
find -path './*' -prune -type d -print0 | xargs -0 <cmds>
untuk mengecualikan direktori tersembunyi:
find -path './[^.]*' -prune -type d
untuk menjalankan beberapa perintah pada nilai yang dikembalikan (contoh yang sangat dibuat-buat):
find -path './[^.]*' -prune -type d -print0 | xargs -0 -I '{}' sh -c \
"printf 'first: %-40s' '{}'; printf 'second: %s\n' '{}'"
alih-alih 'sh -c' juga dapat menggunakan 'bash -c', dll.
... -print0 | xargs -0 ...
jika Anda tidak tahu nama sebenarnya.
find * | while read file; do ...
Anda dapat mengulang semua direktori termasuk direktori tersembunyi (dimulai dengan titik) dalam satu baris dan beberapa perintah dengan:
for file in */ .*/ ; do echo "$file is a directory"; done
Jika Anda ingin mengecualikan symlink:
for file in *; do
if [[ -d "$file" && ! -L "$file" ]]; then
echo "$file is a directory";
fi;
done
catatan: menggunakan daftar */ .*/
berfungsi di bash, tetapi juga menampilkan folder .
dan ..
sementara di zsh tidak akan menampilkan ini tetapi membuang kesalahan jika tidak ada file tersembunyi di folder
Versi yang lebih bersih yang akan menyertakan direktori tersembunyi dan mengecualikan ../ akan dengan opsi dotglob:
shopt -s dotglob
for file in */ ; do echo "$file is a directory"; done
(atau setopt dotglob
dalam zsh)
Anda dapat menghapus dotglob dengan
shopt -u dotglob
Ini akan mencakup jalur lengkap di setiap direktori dalam daftar:
for i in $(find $PWD -maxdepth 1 -type d); do echo $i; done
Gunakan find
dengan -exec
untuk mengulang direktori dan memanggil fungsi di opsi exec:
dosomething () {
echo "doing something with $1"
}
export -f dosomething
find -path './*' -prune -type d -exec bash -c 'dosomething "$0"' {} \;
Gunakan shopt -s dotglob
atau shopt -u dotglob
untuk memasukkan / mengecualikan direktori tersembunyi
ls -l | grep ^d
atau:
ll | grep ^d
Anda dapat mengaturnya sebagai alias
ls
jawaban berbasis ini , yang berisi daftar direktori.
ls
: mywiki.wooledge.org/ParsingLs