Làm cách nào để tôi bảo mkdir thử tạo dir1 và nếu nó đã tồn tại, hãy tạo dir2, v.v., cho đến khi nó chạm vào một tên không tồn tại?


13

Tôi muốn tạo một thư mục có một số ở cuối, ví dụ "dir1" và tăng số đó nếu thư mục đã tồn tại cho đến khi nó chạm vào một tên thư mục không tồn tại và tôi cần thực hiện điều này trong một dòng duy nhất trong một dòng lệnh Linux, đại loại như:

mkdir --increment dir$

Làm thế nào tôi sẽ đi về làm điều đó?

Cho đến nay tôi đã có điều này:

dir=output; n=0; mkdir -p $dir$n; if test -d $dir$n; then n=$((n+1)); echo $dir$n; fi

Nhưng nó chỉ lặp lại tên dir tiếp theo, tôi cần nó để thực hiện đệ quy lệnh.

Câu trả lời:


26

Đây là một bài tập tầm thường trong việc sử dụng while :

n = 0
trong khi ! mkdir dir $ n
làm
    n = $ ((n + 1))
làm xong

Nhưng tất nhiên, không cần suy nghĩ nhiều để nhận ra rằng cơ chế tầm thường này không có quy mô tốt.

Vì vậy, thay vì phát minh lại bánh xe và phải cạo lại tất cả các góc, người ta tạo các thư mục tạm thời duy nhất từ ​​một mẫu hơi khác:

tên = $ (mktemp -d dirXXXXXXXXXXX)


Tìm kiếm nhị phân trên số có thể là đủ tốt.
Thorbjørn Ravn Andersen

Có khá nhiều góc để tránh khỏi nơi bạn bắt đầu trong quá trình tái phát minh bánh xe, không phải là ít nhất trong số đó là ghi nhớ hệ thống tập tin, xem xét bảo mật và song song hóa.
JdeBP

6

Nếu bạn chỉ muốn tăng dần các thư mục được liệt kê theo đúng thứ tự, thay vào đó tôi có thể đề xuất các thư mục được đặt tên dựa trên ngày hiện tại không?

DATE=$(date +%F)
mkdir "dir-$DATE"

Nó sẽ tạo các thư mục với các tên như dir-2014-03-02( YYYY-MM-DD, để xuất hiện theo thứ tự bảng chữ cái).

Nếu bạn tạo nhiều hơn một thư mục mỗi ngày, bạn có thể thêm thời gian hiện tại vào tên tệp. Xem man datecách điều chỉnh định dạng đầu ra của date.


5

trước tiên hãy tìm tên thư mục "lớn nhất", lấy số và tăng dần:

last_dir=(printf "%s\n" dir* | sort -Vr | head -1)
num=$(last_dir#dir)
mkdir "dir$((num+1))"

Đây là một ý tưởng tốt, nhưng không dễ để tương đồng.
Thorbjørn Ravn Andersen

Trừ khi có hàng triệu thư mục, song song hóa chắc chắn là tối ưu hóa sớm.
glenn jackman

Tại sao bạn cần printfở đây? echoCông việc không đơn giản ?
Ruslan

Ngoài ra, tôi sẽ sử dụng dir[0-9]*thay vì dir*.
Ruslan

1
Bạn hiểu lầm rồi. Tôi nói về việc tập lệnh có hợp lý để được chạy nhiều lần cùng một lúc không (nhiều luồng, nhiều người dùng, v.v.) hay không.
Thorbjørn Ravn Andersen

2

Giả sử thư mục của bạn luôn bắt đầu tại "dir1" và không có tệp nào có tên $ dir * (iE chúng đều là các thư mục được đánh số liên tục), bạn có thể thoát khỏi lớp lót này -

mkdir ${dir}$(( `ls ${dir}* | wc -w` + 1 ))

Điều này đếm số lượng tệp bắt đầu bằng $ dir, sau đó thêm một tệp vào số đó và tạo một tệp mới.


0

Phụ lục cho các câu trả lời khác: Nếu bạn cần các thư mục để sắp xếp chính xác theo tên, bạn cũng có thể muốn thêm số thư mục mới (NUM) với các số 0 dẫn đến một độ dài cố định.

Những điều sau đây có thể được cô đọng trên một dòng hoặc được nhúng vào một trong các giải pháp khác.

NUM="00"$NUM                  ## Left zero pad with fixed length - 1 zeros 
NUM=${NUM:((${#NUM} - 3)):3}  ## left trim to fixed length (3 in this case)

Điều này giả định rằng NUM bắt đầu dài ít nhất 1 chữ số và sẽ không vượt quá độ dài cố định. Điều chỉnh cho phù hợp với yêu cầu của bạn.

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.