Lặp qua thư mục và danh sách tập tin


14

Tôi có một thư mục có tên 'mẫu' và nó có 3 tệp trong đó. Tôi muốn viết một tập lệnh shell sẽ đọc các tệp này trong thư mục mẫu và đăng nó lên một trang web HTTP bằng cách sử dụng curl.

Tôi đã viết như sau để liệt kê các tập tin trong thư mục:

for dir in sample/*; do
        echo $dir;
        done

Nhưng nó mang lại cho tôi đầu ra sau:

sample/log

sample/clk

sample/demo

Nó đang đính kèm thư mục cha trong đó. Tôi muốn đầu ra như sau (không có tên thư mục mẹ)

log

clk

demo

Làm thế nào để tôi làm điều này?


1
sử dụng 'cd' đầu tiên. Nếu bạn cần 'curl' nó, bạn vẫn cần nhập thư mục. Ngoài ra, bạn có thể sử dụng echo ${dir##*/}để đưa ra con đường.
eexpress không tưởng

Câu trả lời:


32

Sử dụng basenameđể loại bỏ đường dẫn hàng đầu khỏi các tệp:

for file in sample/*; do
    echo "$(basename "$file")"
done

Mặc dù tại sao không:

( cd sample; ls )

3

Giả sử shell của bạn hỗ trợ nó, bạn có thể sử dụng mở rộng tham số

for path in sample/*; do
    printf -- '%s\n' "${path##*/}"
done

hoặc bạn chỉ có thể thay đổi thư mục đó và thực hiện việc liệt kê ở đó


1
Điều --này là không cần thiết ở đây. Đối số đầu tiên là một chuỗi cố định không có dấu gạch ngang.
Kusalananda

Ngoài ra, ${parameter##pattern}được hỗ trợ bởi tất cả các vỏ POSIX.
Kusalananda

2

Vì các hệ thống * nix cho phép gần như bất kỳ ký tự nào là một phần của tên tệp (bao gồm cả khoảng trắng, dòng mới, dấu phẩy, ký hiệu ống, v.v.), bạn không bao giờ nên phân tích đầu ra của lệnh "ls" trong tập lệnh shell. Nó không đáng tin cậy. Xem lý do tại sao bạn không nên phân tích đầu ra của ls .

Sử dụng "find" để tạo danh sách các tập tin. Nếu bạn đang sử dụng Bash, bạn có thể chèn đầu ra của "find" vào một mảng. Ví dụ dưới đây, với lời cảnh báo mà tôi đã sử dụng lệnh "curl" không hoạt động!

searchDir="sample/"
oldFiles=()
while IFS= read -r -d $'\0' foundFile; do
    oldFiles+=("$foundFile")
done < <(find "$searchDir" -maxdepth 1 -type f -print0 2> /dev/null)

if [[ ${#oldFiles[@]} -ne 0 ]]; then
    for file in "${oldFiles[@]}"; do
        curl -F data=@"$file" UPLOAD_ADDRESS
    done
fi

Thư mục ở đây là gì? $ '\ 0'? Tôi muốn vượt qua một thư mục trong một biến ...
Soylent Graham

searchDir là biến thư mục. "-D $ '\ 0'" đặt dấu phân cách của lệnh đọc thành null.
bb_Vferee

Làm thế nào để tôi đạt được điều tương tự trong vỏ sh? Tôi đang sử dụng #! / Bin / sh
Ayusman

1

Nó phụ thuộc vào những gì bạn muốn làm với các thư mục.

Để chỉ cần in tên, không cần kiểm tra xem đó có phải là thư mục bạn có thể sử dụng ls:

ls -1 sample

Tốt hơn nên tìm, bởi vì bạn có thể sử dụng các bộ lọc:

find sample -type d -maxdepth 1 -printf '%f\n'

Nếu bạn muốn chạy các lệnh trên các tệp, bạn nên sử dụng find và không phải là vòng lặp for:

find sample -type d -maxdepth 1 -exec basename {} \;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.