ฉันจะได้รับคำสั่ง find เพื่อพิมพ์ขนาดไฟล์พร้อมชื่อไฟล์ได้อย่างไร


106

ถ้าฉันออกคำสั่ง find ดังต่อไปนี้:

$ find . -name *.ear

มันพิมพ์ออกมา:

./dir1/dir2/earFile1.ear
./dir1/dir2/earFile2.ear
./dir1/dir3/earFile1.ear

สิ่งที่ฉันต้องการ 'พิมพ์' ในบรรทัดคำสั่งคือชื่อและขนาด:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB

คำตอบ:


109
find . -name '*.ear' -exec ls -lh {} \;

เพียงแค่ชั่วโมงพิเศษจากการตอบกลับของ jer.drab.org ประหยัดเวลาในการแปลงเป็น MB ทางจิตใจ;)


8
เวอร์ชันนี้จะรันกระบวนการ "ls" สำหรับแต่ละไฟล์ หากคุณมีไฟล์จำนวนมาก (เช่นมากกว่าหนึ่งพันไฟล์) คุณควรเพิ่มประสิทธิภาพโดยใช้: find . -name '*.ear' -exec ls -lh {} + \;(นามสกุล GNU) หรือ find . -name '*.ear' -print0 | xargs -0 ls -lh. นอกจากนี้คุณอาจต้องการเพิ่ม-type fหากคุณสนใจเฉพาะไฟล์ (หรือเพิ่ม-dใน ls หากคุณต้องการให้รวมไดเรกทอรีโดยไม่มีเนื้อหา)
ash108

2
คำตอบของคุณไม่ได้ยกเว้นไดเร็กทอรีดังนั้นคุณจะต้องรัน ls ในไดเร็กทอรีด้วยซึ่งเห็นได้ชัดว่าไม่ใช่สิ่งที่ถูกต้อง
ฟ้ามีมิตร

2
นี่เป็นวิธีที่ไม่มีประสิทธิภาพในการทำสิ่งต่างๆ - และน่าเสียดายที่ความคิดเห็นของ ash108 ก็ไม่เหมาะเช่นกัน จะดีกว่ามากถ้าใช้ตัวเลือก -printf เพื่อค้นหา
oskarpearson

คำตอบของ dmazzoni มีประสิทธิภาพมากกว่ามากเพราะหลีกเลี่ยง fork + exec ในทุกไฟล์ (เร็วขึ้น 100 เท่าในเครื่องของฉัน) ฉันต้องเปลี่ยน% k เป็น% s @FaheemMitha: คุณสามารถเพิ่มตัวเลือกเช่น-type fนับเฉพาะไฟล์ปกติ
Mr Fooz

@FaheemMitha วิธีง่ายๆfind . -name "*.ear" -type fสำหรับไฟล์ -type dทำงานสำหรับไดเรกทอรี
anon58192932

111

คุณต้องใช้ -exec หรือ -printf Printf ทำงานดังนี้:

find . -name *.ear -printf "%p %k KB\n"

-exec มีประสิทธิภาพมากขึ้นและให้คุณดำเนินการคำสั่งตามอำเภอใจ - ดังนั้นคุณสามารถใช้เวอร์ชัน 'ls' หรือ 'wc' เพื่อพิมพ์ชื่อไฟล์พร้อมกับข้อมูลอื่น ๆ 'man find' จะแสดงอาร์กิวเมนต์ที่มีให้ printf ซึ่งสามารถทำได้มากกว่าขนาดไฟล์

[แก้ไข] -printf ไม่อยู่ในมาตรฐาน POSIX อย่างเป็นทางการดังนั้นโปรดตรวจสอบว่าเวอร์ชันของคุณรองรับหรือไม่ อย่างไรก็ตามระบบที่ทันสมัยส่วนใหญ่จะใช้ GNU find หรือเวอร์ชันที่ขยายในทำนองเดียวกันดังนั้นจึงมีโอกาสที่จะนำไปใช้


ดูเหมือนว่าตัวอย่างของคุณจะแม่นยำกว่า แต่ฉันไม่สามารถหาตัวอย่างเพื่อใช้กับ Solaris 10 ได้
Brian

ฉันกลัวว่า Solaris find ไม่รองรับ -printf เลย: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html คุณสามารถติดตั้ง GNU ได้หากคุณถูกรบกวนมิฉะนั้นคุณจะต้องใช้ exec หรือ | ตามคำแนะนำของผู้อื่น
Leigh Caldwell

1
+1 สิ่งนี้ดูเหมือนจะสะอาดกว่า ในการจัดรูปแบบผลลัพธ์ฉันต้องการเพิ่มcolumnคำสั่ง find . -name *.ear -printf "%p %k KB\n" | column -t
Amol

1
คำตอบนี้เป็นวิธีที่ถูกต้องมากกว่าคำตอบที่ได้รับการยอมรับ
น่ากลัว

2
-printfตัวเลือกที่ไม่ทำงานใน OS X อย่างใดอย่างหนึ่ง ดูstackoverflow.com/questions/752818/...
abeboparebop

33

วิธีแก้ปัญหาง่ายๆคือใช้ตัวเลือก -ls ในการค้นหา:

find . -name \*.ear -ls

ซึ่งทำให้แต่ละรายการอยู่ในรูปแบบ "ls -l" ปกติ หรือเพื่อให้ได้ผลลัพธ์เฉพาะที่คุณต้องการสิ่งนี้:

find . -name \*.ear -printf "%p\t%k KB\n"

ซึ่งจะให้ชื่อไฟล์ตามด้วยขนาดเป็น KB


ไม่รู้ด้วยซ้ำว่าlsตัวเลือกนี้ควรจะอยู่ในรายการคำตอบสูงกว่าที่เป็นอยู่มาก
Prometheus

24

ใช้ gnu find ฉันคิดว่านี่คือสิ่งที่คุณต้องการ พบไฟล์จริงทั้งหมดไม่ใช่ไดเร็กทอรี (-type f) และสำหรับแต่ละไฟล์จะพิมพ์ชื่อไฟล์ (% p) แท็บ (\ t) ขนาดเป็นกิโลไบต์ (% k) คำต่อท้าย "KB" และจากนั้น ขึ้นบรรทัดใหม่ (\ n)

find . -type f -printf '%p\t%k KB\n'

หากคำสั่ง printf ไม่ได้จัดรูปแบบตามที่คุณต้องการคุณสามารถใช้ exec ตามด้วยคำสั่งที่คุณต้องการเรียกใช้ในแต่ละไฟล์ ใช้ {} สำหรับชื่อไฟล์และยุติคำสั่งด้วยอัฒภาค (;) ในเชลล์ส่วนใหญ่อักขระทั้งสามตัวควรจะถูกหลีกเลี่ยงด้วยแบ็กสแลช

นี่เป็นวิธีง่ายๆที่ค้นหาและพิมพ์ออกมาโดยใช้ "ls -lh" ซึ่งจะแสดงขนาดในรูปแบบที่มนุษย์อ่านได้ (k สำหรับกิโลไบต์, M สำหรับเมกะไบต์):

find . -type f -exec ls -lh \{\} \;

อีกทางเลือกหนึ่งคือ "wc -c" จะพิมพ์จำนวนอักขระ (ไบต์) ในไฟล์:

find . -type f -exec wc -c \{\} \;

+1 ยกเว้นที่ละไว้-name '*.ear'ในตัวอย่างนี่ควรเป็นคำตอบอันดับ 1 ตอบคำถามได้อย่างแม่นยำอธิบายความหมายของไวยากรณ์และให้ทางเลือกหลายทาง
OsakaWebbie

คำตอบนี้ควรได้รับการยอมรับเนื่องจากไม่ได้เรียกใช้คำสั่งใหม่สำหรับทุกบรรทัดจึงเร็วกว่าคำสั่งที่ยอมรับในปัจจุบันจาก shyam มาก
jirislav

อันที่จริงนี่ควรเป็นคำตอบที่ถูกต้อง นอกจากนี้find . -type f -printf '%k KB\t %p\n'เช่นการพิมพ์ขนาดไฟล์ก่อนส่วนใหญ่จะเป็นผลลัพธ์ที่ดีกว่าในแง่ของการจัดรูปแบบเนื่องจากการจัดตำแหน่ง
myradio

8
find . -name '*.ear' -exec du -h {} \;

สิ่งนี้ให้ขนาดไฟล์เท่านั้นแทนที่จะเป็นสิ่งที่ไม่จำเป็นทั้งหมด


wcใช้งานได้ดีกว่านี้หากคุณต้องการขนาดเป็นไบต์
Alex

4

Awk สามารถแก้ไขผลลัพธ์เพื่อให้สิ่งที่ผู้ถามถามหา ในระบบ Solaris 10 ของฉันค้นหา -ls พิมพ์ขนาดเป็น KB เป็นฟิลด์ที่สองดังนั้น:

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

มิฉะนั้นให้ใช้ -exec ls -lh และเลือกฟิลด์ขนาดจากเอาต์พุต อีกครั้งใน Solaris 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear


3

ฉันต่อสู้กับเรื่องนี้บน Mac OS X -printfที่หาคำสั่งไม่สนับสนุน

วิธีแก้ปัญหาที่ฉันพบซึ่งยอมรับว่าอาศัย 'กลุ่ม' สำหรับไฟล์ทั้งหมดที่เป็น 'staff' คือ ...

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/'

สิ่งนี้จะแยกเอาต์พุตยาว ls ออกเป็นสามโทเค็น

  1. สิ่งที่อยู่หน้าข้อความ 'staff'
  2. ขนาดไฟล์
  3. ชื่อไฟล์

จากนั้นจะส่งออกโทเค็น 2 และ 3 นั่นคือเอาต์พุตเป็นจำนวนไบต์แล้วตามด้วยชื่อไฟล์

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php

1
มีประโยชน์ที่ควรทราบ .. GNU เวอร์ชันfindนี้มีให้บริการผ่าน homebrew ด้วยbrew install findutils
mwfearnley

2

สิ่งนี้จะทำให้คุณได้รับสิ่งที่คุณกำลังมองหารวมถึงการจัดรูปแบบ (เช่นชื่อไฟล์ก่อนและขนาดในภายหลัง):

find . -type f -iname "*.ear" -exec du -ah {} \; | awk '{print $2"\t", $1}'

ผลลัพธ์ตัวอย่าง (ที่ฉันเคย-iname "*.php"ได้ผลลัพธ์):

./plugins/bat/class.bat.inc.php  20K
./plugins/quotas/class.quotas.inc.php    8.0K
./plugins/dmraid/class.dmraid.inc.php    8.0K
./plugins/updatenotifier/class.updatenotifier.inc.php    4.0K
./index.php      4.0K
./config.php     12K
./includes/mb/class.hwsensors.inc.php    8.0K

1

คุณสามารถลองสิ่งนี้:

find. -name *.ear -exec du {} \;

ซึ่งจะทำให้คุณมีขนาดเป็นไบต์ แต่คำสั่ง du ยังยอมรับพารามิเตอร์ -k สำหรับ KB และ -m สำหรับ MB มันจะให้ผลลัพธ์เช่น

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear



1

ลองใช้คำสั่งต่อไปนี้:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s" {} ';'

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';'

อย่างไรก็ตามstatไม่ได้มาตรฐานดังนั้นduหรือwcอาจเป็นแนวทางที่ดีกว่า:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'


0

หากคุณต้องการรับขนาดรวมนี่คือข้อเสนอสคริปต์

#!/bin/bash
totalSize=0

allSizes=`find . -type f -name *.ear -exec stat -c "%s" {} \;`

for fileSize in $allSizes; do
    totalSize=`echo "$(($totalSize+$fileSize))"`
done
echo "Total size is $totalSize bytes"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.