array=${ls -d */}
echo ${array[@]}
Mam trzy katalogi: ww
ee
qq
. Chcę je mieć w tablicy, a następnie wydrukuj tablicę.
array=${ls -d */}
echo ${array[@]}
Mam trzy katalogi: ww
ee
qq
. Chcę je mieć w tablicy, a następnie wydrukuj tablicę.
Odpowiedzi:
To byłoby to
array=($(ls -d */))
EDYTUJ: Zobacz rozwiązanie Gordona Davissona, aby uzyskać bardziej ogólną odpowiedź (np. Jeśli twoje nazwy plików zawierają znaki specjalne). Ta odpowiedź jest jedynie poprawką składni.
ARR+=('$(ls -d */)')
do edycji elementów w tablicy, używając pojedynczych cudzysłowów, aby poradzić sobie ze znakami specjalnymi, aby dodać lub usunąć elementy do niej szyk. Pojedyncze cudzysłowy zachowują znaki literału i eliminują potrzebę używania znaków specjalnych, aby zajmować się nimi w nazwach katalogów.
declare -a ARR; ARR+=('$(ls -d "$INPUT_DIR"/*)')
tylko zwraca$(ls -d $INPUT_DIR/*)
ARR+=("$(ls -d */)")
powinno działać. Jeśli nie, daj mi znać.
O ile to możliwe, należy unikać analizowania wyników ls
(zobacz temat wiki Grega ). Zasadniczo wynik ls
będzie niejednoznaczny, jeśli w którejkolwiek nazwie pliku znajdują się zabawne znaki. Zwykle jest to też strata czasu. W tym przypadku, kiedy wykonujesz ls -d */
, dzieje się tak, że powłoka rozwija się */
do listy podkatalogów (która jest dokładnie tym, czego chcesz), przekazuje tę listę jako argumenty do ls -d
, który patrzy na każdy z nich, mówi "tak, to jest katalog w porządku ”i drukuje go (w niespójnym, a czasem niejednoznacznym formacie). ls
Polecenie nie robi nic użytecznego!
Cóż, ok, robi jedną rzecz, która jest przydatna: jeśli nie ma podkatalogów, */
zostanie pozostawiony bez zmian, będzie ls
szukał podkatalogu o nazwie "*", nie będzie go znajdował, wypisze komunikat o błędzie, że nie istnieje (aby stderr) i nie wypisuje "* /" (na standardowe wyjście).
Prostszym sposobem na utworzenie tablicy nazw podkatalogów jest użycie funkcji glob ( */
) bez przekazywania jej do ls
. Ale aby uniknąć umieszczania "* /" w tablicy, jeśli nie ma żadnych podkatalogów, powinieneś najpierw ustawić nullglob (ponownie, zobacz wiki Grega ):
shopt -s nullglob
array=(*/)
shopt -u nullglob # Turn off nullglob to make sure it doesn't interfere with anything later
echo "${array[@]}" # Note double-quotes to avoid extra parsing of funny characters in filenames
Jeśli chcesz wydrukować komunikat o błędzie, jeśli nie ma podkatalogów, lepiej zrób to sam:
if (( ${#array[@]} == 0 )); then
echo "No subdirectories found" >&2
fi
/
w nazwie katalogu?
ls
to proste polecenie. Jego wyjście to stringi. Bash jest zbyt dobry w analizowaniu ciągów. Właściwe wyrażenie regularne to wszystko, co jest potrzebne do bezpiecznego przeanalizowania ls
danych wyjściowych.
ls
robią różne rzeczy z zabawnymi / niedrukowalnymi znakami w nazwach plików, więc nie ma spójnego sposobu na przeanalizowanie wyników w postaci listy nazw plików. I jak powiedziałem, w rzeczywistości nie robi nic użytecznego: jeśli poprawnie przeanalizujesz dane wyjściowe ls -d */
, otrzymasz dokładnie to samo, z czego otrzymasz bezpośrednio */
(z wyjątkiem sytuacji, gdy nie ma dopasowań, a to łatwo sprawdzić).
A lazy sysadmin is a good sysadmin.
być może moje własne ls
parsowanie jest specyficzne dla wersji, którą mam, lub do której jestem przyzwyczajony, ale jak dotąd nie mieli żadnych problemów z dystrybucjami Linuksa, na których je testowałem. Mogę mówić tylko z doświadczenia.
Spowoduje to wydrukowanie plików w tych katalogach wiersz po wierszu.
array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"