คุณจะแสดงรายการจำนวนบรรทัดของทุกไฟล์ในไดเรกทอรีในรูปแบบที่มนุษย์อ่านได้อย่างไร


40

ฉันมีรายการไดเรกทอรีและไดเรกทอรีย่อยที่มีไฟล์ csv ขนาดใหญ่ ไฟล์เหล่านี้มีประมาณ 500 ล้านบรรทัดโดยแต่ละรายการจะมีการบันทึก ผมอยากจะรู้ว่า

  1. มีกี่บรรทัดในแต่ละไฟล์
  2. มีกี่บรรทัดในไดเรกทอรี
  3. จำนวนบรรทัดทั้งหมด

ที่สำคัญที่สุดฉันต้องการสิ่งนี้ใน 'รูปแบบที่มนุษย์อ่านได้' เช่น 12,345,678 มากกว่า 12345678

มันจะเป็นการดีถ้าได้เรียนรู้วิธีการทำ 3 วิธี เครื่องมือทุบตีวานิลลาธรรมดา awk ฯลฯ และ Perl (หรือหลาม)

คำตอบ:


56

มีกี่บรรทัดในแต่ละไฟล์

wcฉันเชื่อว่าใช้มา แต่เดิมสำหรับการนับจำนวนคำ แต่สามารถใช้เส้นคำตัวอักษรไบต์และความยาวบรรทัดที่ยาวที่สุดได้ -lตัวเลือกที่จะบอกว่ามันสายนับ

wc -l <filename>

จะส่งออกจำนวนบรรทัดใน:

$ wc -l /dir/file.txt
32724 /dir/file.txt

คุณยังสามารถไพพ์ข้อมูลด้วยwcเช่นกัน:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

มีกี่บรรทัดในไดเรกทอรี

ลอง:

find . -name '*.pl' | xargs wc -l

อีกหนึ่งซับ:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

BTW wcคำสั่งนับรหัสบรรทัดใหม่ไม่ใช่บรรทัด เมื่อบรรทัดสุดท้ายในไฟล์ไม่ได้ลงท้ายด้วยรหัสบรรทัดใหม่สิ่งนี้จะไม่ถูกนับ

คุณอาจใช้ grep -c ^ ตัวอย่างเต็มรูปแบบ:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

จำนวนบรรทัดทั้งหมด

ไม่แน่ใจว่าฉันเข้าใจว่าคุณร้องขออย่างถูกต้อง เช่นนี้จะแสดงผลลัพธ์ในรูปแบบต่อไปนี้โดยแสดงจำนวนบรรทัดสำหรับแต่ละไฟล์:

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

อีกวิธีหนึ่งในการแสดงผลจำนวนอักขระบรรทัดใหม่ทั้งหมดโดยไม่มีไฟล์ตามจำนวนไฟล์ที่คำสั่งต่อไปนี้สามารถพิสูจน์ได้ว่ามีประโยชน์:

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

ที่สำคัญที่สุดฉันต้องการสิ่งนี้ใน 'รูปแบบที่มนุษย์อ่านได้' เช่น 12,345,678 มากกว่า 12345678

Bash มีฟังก์ชั่นprintfในตัว:

printf "%0.2f\n" $T

เช่นเคยมีหลายวิธีที่สามารถใช้เพื่อให้ได้ผลลัพธ์เดียวกันกับที่กล่าวถึงที่นี่


อย่างไรก็ตามฉันจะใช้ printf ในตัวอย่างของคุณได้อย่างไร ฉันพยายามไปป์จาก wc -l แต่มันไม่ทำงาน
Hexatonic

ลอง> ค้นหา -name '* .pl' | xargs wc -l | awk '{printf ("% 0.2f", $ 1)} {print $ 2}' เปลี่ยนเอาต์พุตของ 'printf' สำหรับความต้องการของคุณ
malyy

สิ่งนี้ไม่ได้เพิ่มเครื่องหมายจุลภาคในจำนวนเพื่อให้อ่านได้ง่ายขึ้น มันแค่เพิ่มศูนย์ไปยังจุดสิ้นสุด
Hexatonic

echo 1000000000000 | xargs printf "% 'd \ n" 1,000,000,000,000
Hexatonic

1
@Hexatonic printfไม่อ่านอาร์กิวเมนต์จากstdinแต่มาจากบรรทัดคำสั่ง (เปรียบเทียบ piping กับechovs piping to cat; catread from stdin, echonot) ใช้printf "$(find ... | xargs ...)"เพื่อระบุเอาต์พุตเป็นอาร์กิวเมนต์printfแทน
BallpointBen

13

ในหลายกรณีการรวมwcคำสั่งและสัญลักษณ์แทน*อาจเพียงพอ
หากไฟล์ทั้งหมดของคุณอยู่ในไดเรกทอรีเดียวคุณสามารถโทร:

wc -l src/*

คุณยังสามารถแสดงรายการไฟล์และไดเรกทอรีต่าง ๆ :

wc -l file.txt readme src/* include/*

คำสั่งนี้จะแสดงรายการไฟล์และจำนวนบรรทัด
บรรทัดสุดท้ายจะเป็นผลรวมของบรรทัดจากไฟล์ทั้งหมด


หากต้องการนับไฟล์ทั้งหมดในไดเรกทอรีซ้ำ:

ก่อนอื่นให้เปิดใช้งาน globstar โดยเพิ่มshopt -s globstarลงใน. bash_profile ของคุณ การสนับสนุนสำหรับ globstar ต้องใช้ Bash ≥ 4.x ซึ่งสามารถติดตั้งได้brew install bashหากจำเป็น bash --versionคุณสามารถตรวจสอบรุ่นของคุณด้วย

จากนั้นเรียกใช้:

wc -l **/*

โปรดทราบว่าผลลัพธ์นี้จะไม่ถูกต้องหากไม่ได้เปิดใช้งาน globstar


และสำหรับการนับไฟล์ในไดเรกทอรี currrent แบบซ้ำ ๆ :wc -l **/*
Taylor Edmiston

@TaylorEdmiston สำหรับฉัน (บน Mac) ที่นับเฉพาะไฟล์เดียวในไดเรกทอรี มันข้ามไฟล์ในไดเรกทอรีปัจจุบันและสำหรับกรณีใด ๆ ที่จะมีมากกว่าหนึ่งไดเรกทอรีลึกมันเตือนว่ามันเป็นไดเรกทอรี: " wc: parent_dir/child_dir: read: Is a directory"
M. Justin

@Thomio มันต้องการให้เปิดใช้งาน globstar สำหรับ macOS ฉันเชื่อว่ามันถูกปิดการใช้งานนอกกรอบ ฉันเพิ่งส่งการแก้ไขคำตอบของคุณซึ่งเพิ่มคำสั่งและวิธีเปิดใช้งาน globstar
Taylor Edmiston

2

คำสั่งนี้จะให้รายการของรหัสบรรทัดในแต่ละไดเรกทอรี:

find . -name '*.*' -type f | xargs wc -l

2

สายไปนิดเกม แต่ฉันได้รับข้อผิดพลาดทะเลาะกันกับข้างต้นเนื่องจากขนาดของ dir สิ่งนี้ใช้ได้กับฉัน:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt


0

catจะรวมไฟล์เป็นหนึ่งเดียวและส่งออกทุกอย่างเป็น stdout คุณสามารถทำสิ่งwc -lต่อไปนี้เพื่อนับจำนวนบรรทัดทั้งหมดของไฟล์ในไดเรกทอรี:

cat /path/to/directory/* | wc -l

0

ฉันจะเพิ่ม @malyy คำตอบสำหรับต่อไปนี้ (เพื่อใหญ่สำหรับความคิดเห็น):

จำนวนบรรทัดทั้งหมด

คำตอบที่หลายคนกำลังใช้ตัวเลือกไฟล์บรรทัดคำสั่งด้วยwc xargsปัญหาเกี่ยวกับสิ่งนี้คือ xargs ถูก จำกัด ไว้ที่ขนาดที่ค่อนข้างเล็กของแพลตฟอร์ม

นอกจากนี้ยังมีความแตกต่างระหว่าง BSD (MacOS) และ GNU (ลินุกซ์ / wchomebrew)

GNU หนึ่งเหมาะสมที่สุดเพราะสามารถอ่านรายการไฟล์จากไฟล์แทนการขัดแย้ง ( --files0)

หากคุณใช้ mac และมี homebrew คุณควรทำสิ่งต่อไปนี้:

find . -name "*.pl" -print0 | gwc -l --files0=-

ขอให้สังเกต GWC แทนการสั่ง wc

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