ฉันสามารถเลือกผลลัพธ์เดียวจาก bash glob ได้หรือไม่


14

ฉันกำลังพยายามเขียนสคริปต์สำหรับงานเพื่อทำให้การรายงานบางอย่างเกี่ยวกับผลลัพธ์เป็นอัตโนมัติ ล็อกไฟล์คือ (ปัจจุบันคือ 'มาตรฐาน' ในอนาคต) เก็บไว้ในโครงสร้างพา ธ ประเภทนี้:

/<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>

ทุกส่วนของเส้นทางนั้นเป็นที่รู้จักยกเว้นการประทับเวลาตามวันเวลาซึ่งเป็นส่วนล่าสุดในโฟลเดอร์เสมอ

ถ้าฉันพยายามใช้ไวด์การ์ดแทนการประทับเวลาฉันจะได้ผลลัพธ์หลายอย่างเช่น:

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

ฉันแค่ต้องการให้ส่งคืนไฟล์ล่าสุดเป็นไปได้ด้วย Bash หรือไม่

NB (ฉันไม่มี zsh และน่ารักอย่างที่มันฟังฉันสงสัยว่าเราจะเอามันไปทำงาน)

คำตอบ:


9

งานต่อไปนี้ใน bash 4.2:

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

หาก bash ของคุณเป็นรุ่นที่เก่ากว่า:

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

สิ่งนี้ใช้ได้กับคอมพิวเตอร์ที่บ้านของฉัน แต่ฉันไม่สามารถรับประกันได้ว่ามันจะทำงานได้หรือไม่
Pureferret

@Pureferret ส่วนที่อาจไม่ทำงานเป็นดัชนีอาร์เรย์เชิงลบ ( -1) สิ่งนี้ถูกเพิ่มเข้ามาใน bash 4.2 RHEL5 น่าจะเป็นดิสทริบิวเตอร์หลักที่เก่าแก่ที่สุดที่รองรับและใช้ bash 4.2.20
Patrick

1
รุ่นที่เก่ากว่าbashมี: "${list[@]: -1}"ชอบในksh93( [-1]มาจากzsh)
Stéphane Chazelas

@ แพทริก - RHEL5 3.2ใช้ทุบตี ยังคงรองรับ RHEL 3 และ 4 ภายใต้อายุการใช้งานที่ยาวนาน
jordanm

1
@Pureferret คุณสามารถคำนวณทางคณิตศาสตร์ด้วยความยาวของอาร์เรย์ดูการแก้ไขของฉัน
Gilles 'หยุดความชั่วร้าย'

10

POSIXly:

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

ตั้งแต่ที่คุณพูดถึงzsh:

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

4

ใช้ bash glob ใน bash สำหรับลูป แบบนี้:

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

ขึ้นอยู่กับความจริงที่ว่า bash ทำการขยายตัวของ glob จัดเรียงตามตัวอักษร อ่านคู่มือทุบตีสำหรับข้อมูลเพิ่มเติม โปรดทราบว่านี้ขึ้นอยู่กับLC_COLLATE นอกจากนี้ยังขึ้นอยู่กับความจริงที่ว่าตัวแปรนั้นfilenameยังคงมีค่าสุดท้ายหลังจากที่ลูปสิ้นสุดลง

หากคุณต้องการชื่อไฟล์ที่มีการประทับเวลาที่เก่าแก่ที่สุดคุณสามารถทำได้เช่นนี้:

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

1

-1 คือค่าเริ่มต้นในไพพ์ไลน์และเอาต์พุต ls ควรเรียงลำดับแล้ว:

ls | tail -n1

หากคนอื่นกำลังมองหาวิธีแทรกผลลัพธ์แรกหรือผลลัพธ์สุดท้ายแบบโต้ตอบคุณสามารถผูกเมนูที่สมบูรณ์หรือเมนูสมบูรณ์ย้อนหลังเป็น. inputrc:

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

หากเปิดใช้งาน show-all-if-ambiguous ให้set completion-query-items 0ลบพรอมต์เมื่อมีผลลัพธ์ 101 รายการขึ้นไปและset page-completions offปิดใช้งานเพจเจอร์


-1
ls -tr | tail -1

ควรทำเคล็ดลับ


3
โปรดทราบว่าคุณไม่ควรแยกการส่งออกของ lsเคย
rahmu

ทำไมถึงเป็นอย่างนั้น? และมันแตกต่างจากการใช้เอาต์พุตจาก glob อย่างไร
slipset

2
mywiki.wooledge.org/ParsingLsอธิบายว่า ...
slipset
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.