ฉันจะเลือกฟิลด์ / คอลัมน์จากผลลัพธ์ของ `ls -l` ได้อย่างไร


22

เป้าหมายของฉันเรียบง่ายหลอกลวง (อย่างน้อยสำหรับฉัน) ฉันต้องการเอาท์พุทของls -lหรือls -lhและเลือกเพียงหนึ่งฟิลด์

ฉันกำลังมองหาสิ่งนี้ว่ากันกระสุนได้มากที่สุดโดยที่ฉันหมายความว่าสมมติว่าชื่อไฟล์สามารถมีจำนวนช่องว่างที่แปรผันไม่ใช่ทุกอย่างในสนามที่มีความยาวเท่ากันเป็นต้น

คะแนนโบนัสสำหรับการมีสคริปต์ที่จะใช้ชื่อของฟิลด์ (หรือแม้แต่เพียงหมายเลขฟิลด์) จากนั้นส่งคืนเนื้อหาของฟิลด์

ฉันอยากจะเลี้ยว

ป้อนคำอธิบายรูปภาพที่นี่

เป็น:

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบ:


41

ลองls -l | awk '{print $7}'ดู

awk เลือกคอลัมน์ดังนั้นมันจึงเหมาะสำหรับงานนี้


3
ตามที่อธิบายโดย @ormaaj: lsไม่ต้องพึ่งพาชิ้นส่วนของข้อมูลการให้บริการในสถานที่เฉพาะเจาะจง findคำสั่งจะเป็นประโยชน์อย่างมาก
Paddy Landau

@PaddyLandau ฉันจะใช้คำสั่ง find เพื่อพิมพ์ขนาดไฟล์เป็นเมกะไบต์อย่างที่ฉันสามารถทำได้ls -l --block-size=Mอย่างไร
SurpriseDog

@Benjamin - lsคำสั่งไม่ใช่มาตรฐาน POSIX ดังนั้นสคริปต์ที่ขึ้นอยู่กับlsอาจแตกบนระบบที่แตกต่างกันหรือแม้กระทั่งในช่วงเวลา ดูคำตอบโดย @ormaaj ในหน้านี้สำหรับรายละเอียดเพิ่มเติม วิธีหนึ่งในการทำสิ่งที่คุณถามคือด้วย Bash loop นี่คือตัวอย่าง for FILENAME in *; do FILESIZE=$(( $( stat --format=%s "${FILENAME}" ) / 1024 )); echo "${FILENAME}" ${FILESIZE}; done. แน่นอนว่าแทนที่จะechoใช้การประมวลผลของคุณ
Paddy Landau

@PaddyLandau ฉันเพิ่งจะวางท่อผลลัพธ์ของคำสั่ง find ... | xargs -d '\n' du -mที่ใช้งานได้เช่นกัน
SurpriseDog

@Benjamin คุณอาจต้องการที่จะดูที่ตัวเลือกในการ-exec find
Paddy Landau

17

LS ไม่เคยแยก ใช้ findGNU stat(1)หรือถ้าพกพาไม่สำคัญ

find . -maxdepth 1 -printf '%Td\n'

สำหรับการอ่านข้อมูลนอกเหนือจากรายการชื่อไฟล์แบบบรรทัดต่อบรรทัดและแยกเป็นฟิลด์ให้ดู: BashFAQ / 001

ไม่มีวิธีใดในการอ่านรายชื่อไฟล์ที่คั่นด้วยบรรทัดใหม่ที่เชื่อถือได้ภายใต้สถานการณ์ส่วนใหญ่


1

คุณสามารถดึงข้อมูลคอลัมน์ที่ระบุในเชลล์เช่น:

ls -al | while read perm bsize user group size month day time file; do echo $day; done

หรือawkตามที่ปรากฏในคำตอบ @Corey , cut -c44-45นอกจากนี้ยังจะทำงานหลังจากที่ปรับตัว (ตั้งแต่lsได้กำหนดคอลัมน์) หรือสิ่งอื่น แต่ปัญหาหลักก็คือว่ามันจะไม่เป็นที่น่าเชื่อถือและกระสุน (เช่นบน Unix มันอาจจะ$6ไม่ได้$7และมัน การเปลี่ยนแปลงขึ้นอยู่กับข้อโต้แย้ง) ทำให้ไม่เหมาะสำหรับเครื่องไม่แนะนำให้แยกlsคำสั่งเลย

วิธีที่ดีที่สุดคือการใช้คำสั่งต่าง ๆ เช่นfindหรือstatซึ่งมีตัวเลือกที่เกี่ยวข้องเพื่อจัดรูปแบบเอาต์พุตตามที่คุณต้องการ ตัวอย่างเช่น:

$ stat -c "%x %n" *
2016-04-10 04:53:07.000000000 +0100 001.txt
2016-04-10 05:08:42.000000000 +0100 7c1c.txt

หากต้องการส่งคืนคอลัมน์ของการแก้ไขเพียงไม่กี่วันให้ลองตัวอย่างนี้:

stat -c "%x" * | while read ymd; do date --date="$ymd" "+%d"; done

มันควรค่าแก่การสังเกตว่า GNU statสามารถมีตัวเลือกต่าง ๆ สำหรับ BSD statดังนั้นมันจะไม่สามารถกันกระสุนในระบบปฏิบัติการที่แตกต่างกันได้


1
+1 สำหรับการกล่าวถึงว่าคำสั่ง ls statไม่ควรแยกวิเคราะห์เช่นเดียวกับการใช้งานของ dateอย่างไรก็ตามมีการตั้งค่าไม่ถูกต้อง คุณควรเพิ่ม--date=$ymdเนื่องจากdateตัวมันเองจะพิมพ์วันที่ปัจจุบัน แต่วัตถุประสงค์ที่นี่คือการแปลงรูปแบบวันที่ของไฟล์
Sergiy Kolodyazhnyy

ls -la | cut -c32-33คำสั่งในความซื่อสัตย์สุจริตรวมเป็นเพียงที่ไม่น่าเชื่อถืออย่างสมบูรณ์ไม่เพียง แต่เนื่องจากข้อผิดพลาดที่เป็นไปได้กับชื่อไฟล์ แต่เพียงเพราะมันขึ้นอยู่กับความยาวและในไฟล์ชื่อผู้ใช้ขนาด stat -c "%x" *.*คำสั่งลักษณะ ok แต่โดยใช้*.*คุณ restricing เฉพาะกับชื่อไฟล์ที่มีจุด ฉันเดาความตั้งใจที่จะจับไฟล์ที่ซ่อนอยู่เช่นกัน ในกรณีนี้คุณควรเปิดใช้งาน globbing สำหรับ dotfiles ล่วงหน้าและใช้*แทน*.*: shopt -s dotglob; stat -c "%x" * | [...].
kos

Ah และสิ่ง Serg กล่าวว่านอกจากนี้ยังมีคุณควรเพิ่ม--date="$ymd"ไปยังdateคำสั่งมิฉะนั้นมันจะพิมพ์วันที่ปัจจุบันของเดือน
kos

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