mkdir -p cho các tập tin


24

mkdir -psẽ tạo một thư mục; nó cũng sẽ làm cho các thư mục cha khi cần thiết.

Có một lệnh tương tự tồn tại cho các tệp, sẽ tạo ra một tệp và thư mục cha khi cần thiết?


Không phải tôi biết .. nhưng bạn chỉ có thể thực hiện mkdir -p / path / to / make && touch / path / to / file ... Điều này sẽ tạo ra một tệp trống trong cấu trúc thư mục mới mà bạn đã tạo tất cả khi cần.

1
@Kansha kết hợp điều đó với dirnamebasenamevà chúng ta sẽ chỉ cần một đối số duy nhất; lợi nhuận! :)

Vâng, gọi tốt.

Câu trả lời:


29

Cài đặt sẽ làm điều này, nếu được cung cấp các tập tin nguồn /dev/null. Đối -Dsố nói để tạo tất cả các thư mục mẹ:

anthony@Zia:~$ install -D /dev/null /tmp/a/b/c
anthony@Zia:~$ ls -l /tmp/a/b/c 
-rwxr-xr-x 1 anthony anthony 0 Jan 30 10:31 /tmp/a/b/c

Không chắc đó có phải là lỗi hay không, hành vi của nó với các tệp thiết bị không được đề cập trong trang chủ. Bạn cũng có thể chỉ cung cấp cho nó một tệp trống ( mktempví dụ mới được tạo với ) làm nguồn.


7

Không, nó không xa như tôi biết. Nhưng bạn luôn có thể sử dụng mkdir -ptouchsau nhau:

f="/a/b/c.txt"
mkdir -p -- "${f%/*}" && touch -- "$f"

3

Tôi thường xuyên gặp phải tình huống này, vì vậy tôi chỉ cần viết một hàm trong .bashrctệp của mình . Có vẻ như thế này

function create() {
    arg=$1
    num_of_dirs=$(grep -o "/" <<< $arg | wc -l)
    make_dirs=$(echo $arg | cut -d / -f1-$num_of_dirs)
    mkdir -p $make_dirs && touch $arg
}

Vì vậy, khi tôi muốn tạo một tệp trong đường dẫn của các thư mục không tồn tại, tôi sẽ nói

create what/is/it  # will create dirs 'what' and 'is', with file 'it' inside 'is'

1
Người đàn ông của tôi! - cảm ơn bạn, tôi đã gọi nó touchp, nhưmkdir -p
ecoologic

0
dir=$(dirname "$f")
test -d $dir || mkdir -p "$dir"

3
Điều testkhông cần thiết; mkdir -pkhông làm gì nếu thư mục đã tồn tại. Thậm chí không trả lại lỗi.
derobert

1
Và tất nhiên, điều này chỉ tạo ra thư mục.
một CVn

0

Tôi sẽ đề nghị vì nó giữ nó trên một dòng, mặc dù việc đặt biến riêng biệt cho phép bạn thay đổi nó và chạy lại lệnh từ lịch sử khá dễ dàng.

B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"

0

Có thể "giả nó".

Đầu tiên, một số lý thuyết bắt buộc:

Rob Griffiths đã đăng một bài viết vào năm 2007 có tựa đề Dễ dàng tạo nhiều thư mục mới trên Macworld.com, trong đó ông đã thảo luận bằng cách sử dụng xargslệnh để đọc trong danh sách các tệp để tạo thư mục bằng cách sử dụng mkdir.

xargscó khả năng tham chiếu một placeholder( {}) với -Icờ, chứa giá trị cho mỗi đối số được truyền vào xargs. Đây là sự khác biệt giữa với cờ đó và không có:

$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt

xargscũng có khả năng chạy các lệnh shell tùy ý với sh -ccờ:

foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'

Kết hợp các khái niệm:

Chúng ta có thể kết hợp các khái niệm này với mkdir -pthay vì mkdirvà khái niệm trong câu trả lời của @ldx để tạo ra điều này:

$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'

Lệnh này về cơ bản ánh xạ từng tên tệp trong một danh sách các tệp được phân tách bằng dòng, loại bỏ phần tệp, tạo các thư mục mkdir -pvà sau đó touches tên tệp trong thư mục tương ứng.

Đây là một sự cố về những gì xảy ra trong lệnh trên:

Nói ví dụ như tôi files.txttrông như thế này:

deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
  • cat files.txt sản xuất deeply/nested/foo/bar.js deeply/nested/baz/fiz.txt
  • deeply/nested/foo/bar.js deeply/nested/baz/fiz.txt được dẫn đến xargs
  • bởi vì chúng tôi đã sử dụng -I {}, xargssẽ dịch từng đối số thành lệnh riêng của nó, vì vậy bây giờ chúng tôi có:
    • deeply/nested/foo/bar.txt
    • deeply/nested/baz/fiz.txt
  • sau đó chúng tôi chạy một lệnh shell sử dụng bộ &&kết hợp để nhóm 3 lệnh chạy tuần tự - lệnh đầu tiên lưu trữ tệp trong một biến môi trường (được sử dụng lại trong lần truyền tệp tiếp theo) bằng cách sử dụng trình giữ chỗ mà chúng tôi đã đăng ký trước đó, vì vậy bây giờ chúng tôi có:
    • f=deeply/nested/foo/bar.txt
    • f=deeply/nested/baz/fiz.txt
  • Bây giờ chúng ta có một biến chúng ta có thể chuyển đến mkdir -p, nhưng chúng ta cần cắt bỏ tên tệp. Đủ đơn giản để sử dụng '${f%/*}':
    • mkdir -p deeply/nested/foo/
    • mkdir -p deeply/nested/baz/
  • và sau đó chúng ta chỉ tham chiếu lại ftoàn bộ biến khi chúng ta touch:
    • touch deeply/nested/foo/bar.txt
    • touch deeply/nested/baz/fiz.txt

2
Bạn có tất cả những lời giải thích này cho những gì thực chất là cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'có UUOC, sau đó bạn chia nhỏ thành xargs mà lại chìm vào vỏ, khi một while readvòng lặp có ý nghĩa hơn
Steven Penny

1
Tôi sẽ thừa nhận tôi không phải là người hiểu rõ nhất về các lệnh * nix - tôi thậm chí không biết UUOC là gì - nhưng tôi không biết đây là một câu trả lời khủng khiếp như thế nào. Nó được nghiên cứu, thử nghiệm và là một giải pháp làm việc cho câu hỏi ban đầu của bạn. Nó mang tính xây dựng (không giống như bình luận khá thô lỗ của bạn). Xin vui lòng, nếu bạn cảm thấy rằng tôi đã làm điều gì đó vô trách nhiệm ở đây mà tôi không nên có, thì hãy giải thích thêm - giải thích lý do tại sao . Tôi không quan tâm lắm đến những cuộc tranh luận không có thực chất.
razorbeard

1
Nhận xét cuối cùng của tôi giải thích nó hoàn hảo. Toàn bộ câu trả lời của bạn có thể được viết tốt hơn như while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txt. Thực tế là bạn không thể thực hiện tìm kiếm trên internet trong 10 giây cho UUOC cũng được kể lại
Steven Penny
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.