mkdir -p
sẽ 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?
dirname
và basename
và chúng ta sẽ chỉ cần một đối số duy nhất; lợi nhuận! :)
mkdir -p
sẽ 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?
dirname
và basename
và chúng ta sẽ chỉ cần một đối số duy nhất; lợi nhuận! :)
Câu trả lời:
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 -D
số 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 ( mktemp
ví dụ mới được tạo với ) làm nguồn.
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 .bashrc
tệ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'
touchp
, nhưmkdir -p
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"
Có thể "giả nó".
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 xargs
lệnh để đọc trong danh sách các tệp để tạo thư mục bằng cách sử dụng mkdir
.
xargs
có khả năng tham chiếu một placeholder
( {}
) với -I
cờ, 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
xargs
cũng có khả năng chạy các lệnh shell tùy ý với sh -c
cờ:
foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'
Chúng ta có thể kết hợp các khái niệm này với mkdir -p
thay vì mkdir
và 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 -p
và sau đó touch
es tên tệp trong thư mục tương ứng.
Nói ví dụ như tôi files.txt
trô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
-I {}
, xargs
sẽ 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
&&
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
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/
f
toàn bộ biến khi chúng ta touch
:
touch deeply/nested/foo/bar.txt
touch deeply/nested/baz/fiz.txt
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 read
vòng lặp có ý nghĩa hơn
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