ทำไม wc <<<“ $ string” แสดงความยาวหนึ่งไบต์นานกว่า printf“ $ string” | ห้องน้ำ?


11

โดยบังเอิญฉันพบว่าwcนับแตกต่างกันขึ้นอยู่กับว่ามันได้รับข้อมูลจากทุบตี:

$ s='hello'
$ wc -m <<<"$s"
6
$ wc -c <<<"$s"
6
$ printf '%s' "$s" | wc -m
5
$ printf '%s' "$s" | wc -c
5

นี่คือ - IMHO ทำให้สับสน - พฤติกรรมมีการบันทึกไว้ที่อื่นหรือไม่ สิ่งที่wcนับที่นี่ - นี่คือการขึ้นบรรทัดใหม่หรือไม่


3
คุณสามารถไปที่od -cเพื่อดูสิ่งที่คุณมีอยู่เสมอ
Thorbjørn Ravn Andersen

xxd -g1หรือดีกว่า
Ruslan

1
ฉันหวังว่าprintf "$s"ไม่ใช่สคริปต์ที่แท้จริงของคุณ ... หวังว่าคุณจะหมายถึงprintf "%s" "$s"
user541686

เนื่องจากมีความคิดเห็นมากมายเกี่ยวกับ printf ฉันจึงแก้ไขโพสต์ของฉันเพื่อสะท้อนแนวปฏิบัติที่ดีที่สุด
rexkogitans

คำตอบ:


38

ความแตกต่างเกิดจากการขึ้นบรรทัดใหม่ที่เพิ่มในสตริงที่นี่ ดูคู่มือ Bash :

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

wc กำลังนับในวิธีเดียวกัน แต่อินพุตนั้นแตกต่างกัน


7
หากควรสังเกตว่าการพิมพ์เนื้อหา (โดยพลการ) ของตัวแปรโดยไม่มีอักขระขึ้นบรรทัดใหม่ควรเป็นprintf %s "$var"(หรือprint -rn -- "$var"ด้วยเชลล์ ksh-like) printf "$var"ซึ่งไม่สามารถใช้งานได้อย่างถูกต้องสำหรับค่าของอักขระ$varที่มี%หรือเครื่องหมายแบ็กสแลช (หรือ เริ่มต้นด้วย-การใช้งานส่วนใหญ่)
Stéphane Chazelas

โปรดทราบว่าการใช้สตริงที่นี่ดั้งเดิมในพอร์ต Unix rcไม่ได้เพิ่มอักขระขึ้นบรรทัดใหม่
Stéphane Chazelas

26

มันขึ้นบรรทัดใหม่ที่ประสบความสำเร็จโดยเพิ่มที่นี่ - เปลี่ยนเส้นทางสตริง:

$ s="hello"
$ hexdump -C <<<"$s"
00000000  68 65 6c 6c 6f 0a                                 |hello.|
00000006
$ printf "$s" | hexdump -C
00000000  68 65 6c 6c 6f                                    |hello|
00000005
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.