วิธีรับ“ wc -l” เพื่อพิมพ์จำนวนบรรทัดโดยไม่มีชื่อไฟล์ได้อย่างไร


155
wc -l file.txt

ส่งออกจำนวนบรรทัดและชื่อไฟล์

ฉันต้องการเพียงตัวเลขเอง (ไม่ใช่ชื่อไฟล์)

ฉันสามารถทำได้

 wc -l file.txt | awk '{print $1}'

แต่อาจจะมีวิธีที่ดีกว่า


13
wc -l < file.txtทำงานได้อย่างแม่นยำและรัดกุม
Jonathan Leffler


3
นี่เป็นคำถามที่ฉันค้นหามาสองครั้งแล้ว พฤติกรรมของ wc นี้ไม่ได้ใช้งานง่ายและต่อต้านกระบวนทัศน์สำหรับ -nix terseness ปกติ ความตึงนั้นมีเหตุผลเพราะคุณไม่ต้องการที่จะหลีกเลี่ยงความซ้ำซ้อนทุกประเภท ท้ายที่สุดฉันรู้ชื่อไฟล์ใช่ไหม สิ่งที่ฉันต้องการคือการนับบรรทัด
ปีเตอร์ - Reinstate Monica

คำตอบ:


217

ลองด้วยวิธีนี้:

wc -l < file.txt

5
ใน AIX, ksh สิ่งนี้จะมีช่องว่างนำหน้าหมายเลขเสมอ เราต้องใช้ | awk '{พิมพ์ $ 1}' หรือเครื่องหมายตัดเพื่อตัดช่องว่าง อีกวิธีในการตัดแต่งก็คือการใส่เสียงสะท้อน
rao

@rao ถูกต้องจะเป็นการเพิ่มช่องว่างหน้าหมายเลข โซลูชันของฉันแก้ปัญหานี้และทำได้ง่ายกว่า awk หรือ cut
Desi Cochrane

@rao ไม่มีที่ว่างสำหรับทุบตี พื้นที่มาจากไหนใน ksh wc -lไม่ควรปล่อยหนึ่งและทำไม ksh จะเติมเอาต์พุตมาตรฐานของโปรแกรมด้วยช่องว่าง?
Peter - Reinstate Monica

ในขณะที่นี่เป็นวิธีแก้ปัญหาที่ถูกต้อง (และเป็นเรื่องง่ายพอที่ wc ไม่เคยได้รับการแก้ไข) ก็มีแนวโน้มที่จะช้าลงและไม่ได้ใช้งานง่าย สำหรับหนึ่งฉันคาดหวังบางอย่างเช่น4711 [stdin]เอาท์พุท
ปีเตอร์ - Reinstate Monica

ยังพิจารณาการจับคู่กับprintf "%'d"ซึ่งดูแลพื้นที่และพิมพ์จำนวนมากอย่าง
ลีโอ

21
cat file.txt | wc -l

ตามหน้า man (สำหรับรุ่น BSD ฉันไม่มี GNU version เพื่อตรวจสอบ):

หากไม่ได้ระบุไฟล์จะใช้อินพุตมาตรฐานและไม่มีชื่อไฟล์แสดงขึ้น พรอมต์จะยอมรับอินพุตจนกว่าจะได้รับ EOF หรือ [^ D] ในสภาพแวดล้อมส่วนใหญ่


3
ฉันไม่ชอบแมวการเรียงต่อกันใช้เวลามาก
PoGibas

9
wc -l < file.txtมีผลเหมือนกัน
pjmorse

@user: ทดสอบ โดยส่วนที่ช้าที่สุดจะอ่านไฟล์จากดิสก์
sarnold

11
@ user1286528 จากนั้นใช้wc -l < file.txtเพื่อหลีกเลี่ยงการใช้แมวที่ไร้ประโยชน์ แม้ว่าคุณจะเป็นคนบ้าอย่างแน่นอนถ้าคุณคิดว่ามันใช้เวลาที่สังเกตได้
ฮอบส์

12

หากต้องการทำสิ่งนี้โดยไม่มีช่องว่างนำทำไม:

wc -l < file.txt | bc

ฉันได้รับข้อผิดพลาดทางไวยากรณ์กับสิ่งนี้ (Ubuntu 14.04) ฉันคิดว่ามีปัญหากับชื่อไฟล์
ลด

บน RHEL 6.7 จะทำให้เกิดข้อผิดพลาด: $ wc -l file.csv | bc (standard_in) 1: ข้อผิดพลาดทางไวยากรณ์ (standard_in) 1: อักขระที่ผิดกฎหมาย: N (standard_in) 1: ข้อผิดพลาดทางไวยากรณ์ (standard_in) 1: ข้อผิดพลาดทางไวยากรณ์
Rodrigo Hjort

3
ฉันยังได้รับข้อผิดพลาดในการแยกวิเคราะห์ แต่คุณสามารถรวมนี้กับคำตอบอื่น ๆ ที่จะใช้wc -l < file.txtในการแก้ไขข้อผิดพลาดในการแยกวิเคราะห์และถอดพื้นที่:wc -l < file.txt | bc
jangosteve

11

เกี่ยวกับ

wc -l file.txt | cut -d' ' -f1

ie ไปป์เอาท์พุทของwcเข้าสู่cut(ที่ตัวคั่นเป็นช่องว่างและเลือกเพียงสนามแรก)


4
นี่ไม่ได้ดีไปกว่าwc -l file.txt | awk '{print $1}'OP ที่ได้ลองไปแล้ว
doubleDown

1
เร็วกว่าwc -l < file.txtวิธี แต่ต้องใช้| cut -d' ' -f2กับ BSD ตราบใดที่wcคำสั่งส่งคืนพื้นที่นำหน้าตัวอย่าง: "34068289 file.txt" แทนที่จะเป็น "34068289 file.txt"
Sopalajo de Arrierez

@doubleDown ดีการใช้ awk ก็เหมือนกับการใช้เครื่อง CNC เพื่อตัดบอร์ดแทนเลื่อย ใช้เลื่อยสำหรับเลื่อย
ปีเตอร์ - Reinstate Monica

5

การเปรียบเทียบเทคนิค

ฉันมีปัญหาคล้ายกันที่พยายามรับจำนวนตัวอักษรโดยไม่มีช่องว่างwcนำหน้าซึ่งให้ฉันมาที่หน้านี้ หลังจากลองคำตอบที่นี่ต่อไปนี้เป็นผลลัพธ์จากการทดสอบส่วนตัวของฉันใน Mac (BSD Bash) นี่คือการนับจำนวนตัวอักษร wc -lสำหรับสายการนับที่คุณต้องการจะทำอย่างไร echo -nละเว้นตัวแบ่งบรรทัดต่อท้าย

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

ฉันจะไม่พึ่งพาcut -f*วิธีการทั่วไปเนื่องจากต้องการให้คุณทราบจำนวนช่องว่างที่แน่นอนที่มีเอาต์พุตใด ๆ และอันนั้นgrepใช้ได้กับการนับจำนวนบรรทัด

bcมีความรัดกุมที่สุดawkและperlดูเกินความจริงเล็กน้อย แต่ทั้งหมดนี้ควรจะค่อนข้างเร็วและพกพาได้เพียงพอ

นอกจากนี้โปรดทราบว่าบางส่วนของสิ่งเหล่านี้สามารถปรับให้เข้ากับการตัดช่องว่างโดยรอบจากสายทั่วไปได้เช่นกัน (รวมถึงecho `echo $FOO`กลอุบายอื่น ๆ )


1
echo $(printf '%s' "$FOO" | wc -c)เป็นหนึ่งในโอกาสที่หายากเมื่อechoมีคำสั่งย่อยไม่ได้ไร้ประโยชน์
tripleee

@tripleee Whoa ... ตามโค้ดของคุณมันecho `echo $FOO`;ก็เหมือนกับคำสั่ง String.trim () บนตัวแปร! มันมีประโยชน์อย่างน่าอัศจรรย์ ฉันจะเพิ่มบรรทัดของคุณในคำตอบของฉันด้วย
Beejor



4

เกี่ยวกับ

grep -ch "^" file.txt

3
ดี การใช้งานที่เป็นต้นฉบับ / สร้างสรรค์มากgrepแต่การตรวจสอบสิ่งนี้ปรากฎ (ไม่แปลกใจ) ว่าจะช้าลงเป็น 2x ถึง 6x กว่าวิธีที่เรียบง่าย / ตรงไปตรงมาwcในการทดสอบของฉัน
arielf

3

เห็นได้ชัดว่ามีวิธีแก้ไขปัญหานี้มากมาย นี่คืออีกหนึ่งแม้ว่า:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

นี้เท่านั้น outputs จำนวนเส้น แต่ตัวอักษรต่อท้ายบรรทัดใหม่ ( \n) เป็นปัจจุบันถ้าคุณไม่ต้องการที่ทั้งแทนที่ด้วย[:blank:][:space:]


ปัญหานี้เกิดขึ้นเมื่อชื่อไฟล์มีตัวเลขอยู่ในนั้น ตัวอย่างเช่นไฟล์ที่test9มี 1 บรรทัดในนั้นเอาต์พุตจะเป็น 19
Raphael Ahrens

1

วิธีที่ดีที่สุดคืออันดับแรกค้นหาไฟล์ทั้งหมดในไดเรกทอรีจากนั้นใช้ AWK NR (Number of Records Variable)

ด้านล่างเป็นคำสั่ง:

find <directory path>  -type f | awk  'END{print NR}'

ตัวอย่าง: - find /tmp/ -type f | awk 'END{print NR}'


0

มันใช้งานได้สำหรับฉันโดยใช้แบบปกติwc -lและsedเพื่อลบอักขระใด ๆ ที่ไม่ใช่ตัวเลข

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

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