array=${ls -d */}
echo ${array[@]}
Tôi có ba thư mục: ww
ee
qq
. Tôi muốn chúng trong một mảng và sau đó in mảng.
array=${ls -d */}
echo ${array[@]}
Tôi có ba thư mục: ww
ee
qq
. Tôi muốn chúng trong một mảng và sau đó in mảng.
Câu trả lời:
Nó sẽ là cái này
array=($(ls -d */))
CHỈNH SỬA: Xem giải pháp của Gordon Davisson để có câu trả lời tổng quát hơn (nghĩa là nếu tên tệp của bạn chứa các ký tự đặc biệt). Câu trả lời này chỉ là một sửa cú pháp.
ARR+=('$(ls -d */)')
để chỉnh sửa các phần tử trong một mảng, trong khi sử dụng dấu ngoặc kép để xử lý các ký tự đặc biệt, để thêm hoặc xóa các phần tử của mảng đó mảng. Dấu ngoặc kép duy trì các ký tự chữ và loại bỏ bất kỳ yêu cầu thoát nào để xử lý chúng trong tên thư mục.
declare -a ARR; ARR+=('$(ls -d "$INPUT_DIR"/*)')
lợi nhuận chỉ$(ls -d $INPUT_DIR/*)
ARR+=("$(ls -d */)")
nên làm việc. Nếu không chỉ cho tôi biết.
Bất cứ khi nào có thể, bạn nên tránh phân tích cú pháp đầu ra của ls
(xem wiki của Greg về chủ đề này ). Về cơ bản, đầu ra của ls
sẽ không rõ ràng nếu có các ký tự hài hước trong bất kỳ tên tệp nào. Nó cũng thường lãng phí thời gian. Trong trường hợp này, khi bạn thực thi ls -d */
, điều xảy ra là trình bao mở rộng */
thành danh sách các thư mục con (đã chính xác là những gì bạn muốn), chuyển danh sách đó dưới dạng các đối số ls -d
, nhìn vào từng đối số, nói "vâng, đó là một thư mục được rồi ”và in nó (ở định dạng không nhất quán và đôi khi không rõ ràng). Các ls
lệnh không được làm bất cứ điều gì hữu ích!
Chà, được rồi, nó đang làm một điều hữu ích: nếu không có thư mục con nào, */
sẽ được sang trái như cũ, ls
sẽ tìm kiếm thư mục con có tên "*", không tìm thấy nó, in một thông báo lỗi rằng nó không tồn tại (để stderr), và không in "* /" (sang stdout).
Cách rõ ràng hơn để tạo một mảng tên thư mục con là sử dụng global ( */
) mà không chuyển nó tới ls
. Nhưng để tránh đặt "* /" trong mảng nếu không có thư mục con thực sự, bạn nên đặt nullglob trước (một lần nữa, hãy xem wiki của Greg ):
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
Nếu bạn muốn in thông báo lỗi nếu không có thư mục con nào, tốt hơn hết bạn nên tự thực hiện:
if (( ${#array[@]} == 0 )); then
echo "No subdirectories found" >&2
fi
/
trong tên dir?
ls
là một lệnh đơn giản. Đầu ra của nó là chuỗi. Bash cực kỳ giỏi trong việc phân tích chuỗi. Regex thích hợp là tất cả những gì cần thiết để phân tích cú pháp ls
đầu ra một cách an toàn .
ls
khác nhau làm những việc khác nhau với các ký tự vui nhộn / không in trong tên tệp, vì vậy không có cách nào nhất quán để phân tích đầu ra của nó thành danh sách tên tệp. Và như tôi đã nói, nó không thực sự làm bất cứ điều gì hữu ích: nếu bạn phân tích cú pháp chính xác đầu ra của nó ls -d */
, bạn sẽ kết thúc với chính xác thứ mà bạn nhận được trực tiếp từ đó */
(ngoại trừ khi không có kết quả phù hợp và điều đó dễ dàng kiểm tra).
A lazy sysadmin is a good sysadmin.
Có lẽ cách ls
phân tích cú pháp của riêng tôi dành riêng cho phiên bản tôi có, hoặc phiên bản tôi đã quen, nhưng cho đến nay chúng không có vấn đề gì trên các bản phân phối linux mà tôi đã thử nghiệm. Tôi chỉ có thể nói từ kinh nghiệm.
Điều này sẽ in các tệp trong các thư mục đó từng dòng một.
array=(ww/* ee/* qq/*)
printf "%s\n" "${array[@]}"