Tôi chỉ có thể chọn một kết quả từ một bash global?


14

Tôi đang cố gắng viết một kịch bản cho công việc để tự động hóa một số báo cáo về đầu ra. Các tệp Nhật ký (hiện tại, nó đang được 'chuẩn hóa' trong tương lai) được lưu trữ trong loại cấu trúc đường dẫn này:

/<root_path>/<process_one_path>/logs/<time_date_stamp>/<specific_log_file>

/<root_path>/<process_two_path>/logs/<different_time_date_stamp>/<specific_log_file>

Mọi phần của đường dẫn đều được biết ngoại trừ tem ngày giờ, luôn là phần mới nhất trong thư mục.

Nếu tôi cố gắng sử dụng thẻ hoang dã thay cho dấu ngày, tôi nhận được nhiều kết quả, ví dụ:

> ls /<root_path>/<process_two_path>/logs/* [tab]
20130102-175103
20130118-090859
20130305-213506

Tôi chỉ muốn nó trả lại cái mới nhất, điều này có thể với Bash không?

NB (Tôi không có zsh, và đáng yêu như nó có vẻ như tôi nghi ngờ chúng ta sẽ có được nó tại nơi làm việc)

Câu trả lời:


9

Các hoạt động sau đây trong bash 4.2:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[-1]}"

Nếu bash của bạn là phiên bản cũ hơn:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[${#list[@]}-1]}"

Điều này chắc chắn hoạt động trên máy tính ở nhà của tôi nhưng tôi không thể đảm bảo nó sẽ hoạt động tại nơi làm việc?
Pureferret

@Pureferret phần có thể không hoạt động là chỉ số mảng âm ( -1). Điều này đã được thêm vào trong bash 4.2. RHEL5 có lẽ là bản phân phối doanh nghiệp chính được hỗ trợ lâu đời nhất hiện có và nó sử dụng bash 4.2.20.
Patrick

1
Các phiên bản cũ hơn bashcó: "${list[@]: -1}"like in ksh93( [-1]đến từ zsh).
Stéphane Chazelas

@Patrick - RHEL5 sử dụng bash 3.2. RHEL 3 và 4 vẫn được hỗ trợ trong cuộc sống kéo dài.
jordanm

1
@Pureferret Bạn cũng có thể thực hiện số học với độ dài mảng, xem phần chỉnh sửa của tôi.
Gilles 'SO- đừng trở nên xấu xa'

10

POSIXly:

 set -- /<root_path>/<process_two_path>/logs/*
 shift "$(($# - 1))"
 printf '%s\n' "$1"

Kể từ khi bạn đề cập zsh:

 print -r /<root_path>/<process_two_path>/logs/*([-1])

4

Sử dụng bash global trong một bash for loop. Như thế này:

for filename in <logdir>/*; do :; done; echo "$filename"

Điều này phụ thuộc vào thực tế là bash không mở rộng toàn cầu được sắp xếp theo thứ tự abc. Đọc hướng dẫn sử dụng bash để biết thêm thông tin. Lưu ý rằng điều này phụ thuộc vào LC_COLLATE . Điều này cũng phụ thuộc vào thực tế là biến filenamevẫn chứa giá trị cuối cùng sau khi vòng lặp kết thúc.

Nếu bạn muốn tên tệp có dấu thời gian cũ nhất, bạn có thể làm như thế này:

for filename in <logdir>/*; do echo "$filename"; break; done

1

-1 là mặc định trong các đường ống và đầu ra ls đã được sắp xếp:

ls | tail -n1

Nếu những người khác đang tìm cách chèn kết quả đầu tiên hoặc cuối cùng một cách tương tác, bạn có thể liên kết trình đơn hoàn thành hoặc trình đơn hoàn thành ngược trong .inputrc:

"\e\t": menu-complete
"\e[Z": menu-complete-backward # shift-tab

Nếu hiển thị tất cả nếu mơ hồ được bật, hãy set completion-query-items 0xóa lời nhắc khi có 101 kết quả trở lên và set page-completions offvô hiệu hóa máy nhắn tin.


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.