2014-05-02 14 views
7

Tôi cần tải tệp đầu tiên trong một thư mục có phần mở rộng là .tar.gz. Tôi đã đưa ra:Lấy tệp đầu tiên của tiện ích mở rộng nhất định từ một thư mục

FILE=/path/to/folder/$(ls /path/to/folder | grep ".tar.gz$" | head -1) 

nhưng tôi cảm thấy nó có thể được thực hiện đơn giản và thanh lịch hơn. Có giải pháp nào tốt hơn không?

+1

Làm thế nào để bạn xác định "đầu tiên"? Sắp xếp theo thứ tự chữ cái, sắp xếp kích thước? – indivisible

+0

Về mặt lý thuyết, thứ tự thứ tự tăng dần theo thứ tự abc, thực tế sẽ có một tệp duy nhất của phần mở rộng đó ... – linkyndy

Trả lời

11

Bạn có thể nhận được tất cả các tập tin trong một mảng, và sau đó nhận được sự mong muốn một:

files=(/path/to/folder/*.tar.gz) 

Lấy file đầu tiên:

echo "${files[0]}" 

Lấy tập tin cuối cùng:

echo "${files[${#files[@]}-1]}" 

Bạn có thể muốn đặt tùy chọn vỏ nullglob để xử lý các trường hợp khi không có matc tệp hing:

shopt -s nullglob 
+0

Có vẻ như một chút quá mức cần thiết, biến thể của tôi có ít dòng hơn mặc dù nó có một số mã dự phòng ... – linkyndy

+0

@AndreiHorak hiểu câu hỏi. Nếu bạn biết đường dẫn và phần mở rộng của tệp, có nhiều cách tốt hơn so với _parsing 'ls'_. Ví dụ: 'echo /path/*.tar.gz | cut -d '' -f1' giả định tên tập tin không có dấu cách. – devnull

+2

2 nhận xét: 1. để echo phần tử cuối cùng của mảng 'files', lệnh' echo "$ {files [-1]}" 'cũng sẽ hoạt động. 2. Nếu không có tập tin (và 'nullglob') được thiết lập, bạn sẽ nhận được một lỗi _bad mảng subscript_.Trong trường hợp này, bạn có thể muốn thay thế bằng '(($ {# files [@]})) && echo" $ {files [-1]} "'. –

1

đây là phiên bản ngắn hơn từ ý tưởng của riêng bạn.

FILE=$(ls /path/to/folder/*.tar.gz| head -1) 
3

Bạn có thể sử dụng set như minh họa bên dưới. Vỏ sẽ mở rộng ký tự đại diện và set sẽ chỉ định các tập tin như tham số vị trí mà có thể được truy cập bằng $1, $2, vv

# set nullglob so that if no matching files are found, the wildcard expands to a null string 
shopt -s nullglob 

set -- /path/to/folder/*.tar.gz 

# print the name of the first file 
echo "$1" 

Nó không phải là thực hành tốt để parse ls như bạn đang làm, bởi vì nó sẽ không xử lý tên tập tin chứa ký tự dòng mới. Ngoài ra, grep là không cần thiết vì bạn có thể chỉ cần thực hiện ls /path/to/folder/*.tar.gz | head -1.

2

Đây là một cách để thực hiện điều đó:

for FILE in *.tar.gz; do break; done 

Bạn nói bash-break vòng lặp trong phiên đầu tiên, chỉ khi tên tập tin đầu tiên được gán cho FILE.


Một cách khác để làm điều tương tự:

first() { FILE=$1; } && first *.tar.gz 

Ở đây bạn đang sử dụng các tham số vị trí của hàm first đó là tốt hơn so với set các tham số vị trí của toàn bộ quá trình bash của bạn (như với set --) .

Các vấn đề liên quan