คว้าตัวอักษร [x] ตัวแรกสำหรับสตริงจากไพพ์


58

หากฉันมีเอาต์พุตที่ยาวมากจากคำสั่ง (บรรทัดเดียว) แต่ฉันรู้ว่าฉันต้องการเพียงแค่ [x] (สมมติว่า 8) ตัวอักษรของเอาต์พุตเป็นวิธีที่ง่ายที่สุดในการรับสิ่งนั้น ไม่มีตัวคั่นใด ๆ


คำตอบ:


82

วิธีหนึ่งคือการใช้cut:

 command | cut -c1-8

สิ่งนี้จะให้อักขระ 8 ตัวแรกของแต่ละบรรทัดของเอาต์พุต เนื่องจากcutเป็นส่วนหนึ่งของ POSIX จึงมีแนวโน้มที่จะอยู่ใน Unices ส่วนใหญ่


3
โปรดทราบว่าcut -cเลือกอักขระ cut -bหรือhead -cเลือกไบต์ สิ่งนี้สร้างความแตกต่างในบางภาษา (ในทางปฏิบัติเมื่อใช้ UTF-8)
Gilles 'หยุดความชั่วร้าย'

คุณไม่จำเป็นต้องระบุดัชนีเริ่มต้นในกรณีนี้ การพูดcut -c-8จะเลือกจากตัวละคร 1 ถึง 8
Sparhawk

@Steven cutเทียบเท่ากับ Windows คืออะไร
Pacerier

command | dd bs=8 count=1 2>/dev/nullด้วย ไม่ได้บอกว่ามันสั้นกว่าหรือเหนือกว่า ทางเลือกอื่น
dubiousjim

@Gilles แต่ทราบว่ากับรุ่นปัจจุบันของ GNU cut, cut -cทำงานเหมือนcut -b(นั่นคือมันไม่ทำงานอย่างถูกต้องสำหรับอักขระหลายไบต์)
Stéphane Chazelas

24

นี่คือวิธีอื่น ๆ ในการรับเพียง 8 ตัวอักษรแรก

command | head -c8

command | awk '{print substr($0,1,8);exit}' 

command | sed 's/^\(........\).*/\1/;q'

และถ้าคุณทุบตี

var=$(command)
echo ${var:0:8}

2
ฉันคิดว่าสูตร sed ต่อไปนี้อ่านง่ายขึ้นนิดหน่อย: command | sed 's/\(.\{8\}\).*/\1/'หรือถ้า sed ของคุณสนับสนุน: command | sed -r 's/(.{8}).*/\1/'; มิฉะนั้น +1
Steven D

สิ่งที่ดี แต่โปรดทราบว่าhead -cนับเป็นไบต์ไม่ใช่ตัวอักษร ในทำนองเดียวกันในการใช้งาน Awk ที่สำคัญมีเพียงGNU awk ที่จัดการอักขระหลายไบต์อย่างถูกต้อง - FreeBSD Awk และ Mawk ไม่
mklement0

2

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

read -n8 -d$'\0' -r <(command)

หลังจากรันตัวละครของคุณจะเป็นตัวแปรในเปลือกread ... <(command) REPLYพิมพ์help readเพื่อเรียนรู้เกี่ยวกับตัวเลือกอื่น ๆ

คำอธิบาย: -n8อาร์กิวเมนต์ที่readบอกว่าเราต้องการได้สูงสุด 8 ตัวอักษร -d$'\0'กล่าวอ่านจนกว่าโมฆะมากกว่าที่จะขึ้นบรรทัดใหม่ วิธีนี้การอ่านจะดำเนินต่อไป 8 อักขระแม้ว่าหนึ่งในอักขระก่อนหน้านี้จะเป็นบรรทัดใหม่ (แต่ไม่ใช่ถ้าเป็นโมฆะ) อีกทางเลือกหนึ่ง-n8 -d$'\0'คือใช้-N8ซึ่งจะอ่านได้ถึง 8 ตัวอักษรหรือจนกว่า stdin จะถึง EOF ไม่มีตัวคั่นใดให้เกียรติ ที่น่าจะเหมาะกับความต้องการของคุณดีกว่า แต่ผมไม่ทราบว่าหลายเฉพาะหน้าเปลือกหอยได้อ่านว่าเกียรตินิยม-Nเมื่อเทียบกับการเคารพและ-n -dต่อเนื่องกับคำอธิบาย: -rบอกว่าไม่สนใจ\-escapes เพื่อให้ตัวอย่างเช่นที่เราปฏิบัติเป็นสองตัวละครมากกว่าที่จะเป็นหนึ่งเดียว\\\

ในที่สุดเราก็ทำread ... <(command)มากกว่าcommand | read ...เพราะในรูปแบบที่สองการอ่านจะถูกดำเนินการใน subshell ซึ่งออกแล้วทันทีสูญเสียข้อมูลที่คุณเพิ่งอ่าน

ตัวเลือกอื่นคือทำการประมวลผลทั้งหมดของคุณภายใน subshell ตัวอย่างเช่น:

$ echo abcdefghijklm | { read -n8 -d$'\0' -r; printf "REPLY=<%s>\n" "$REPLY"; }
REPLY=<abcdefgh>

1
หากคุณเพียงแค่ต้องการที่จะส่งออก 8 cutตัวอักษรและไม่จำเป็นต้องดำเนินการให้ในเปลือกแล้วเพียงแค่ใช้
dubiousjim

ดีที่จะรู้เกี่ยวกับread -n <num>; ข้อแม้เล็ก ๆ : Bash 3.x (ปัจจุบันยังคงอยู่บนระบบปฏิบัติการ) ตีความผิดพลาด<num>เป็นจำนวนไบต์และทำให้ล้มเหลวด้วยอักขระหลายไบต์; สิ่งนี้ได้รับการแก้ไขใน Bash 4.x
mklement0

นี่เป็นคำตอบที่ดีและมีประโยชน์ ทั่วไปมากขึ้นกว่าคนอื่น ๆ
not2qubit

2

อีกหนึ่งโซลูชั่นซับโดยใช้การขยายพารามิเตอร์

echo ${word:0:x}

EG: word="Hello world"
echo ${word:0:3} or echo ${word::3} 
o/p: Hel


EG.2: word="Hello world"
echo ${word:1:3}
o/p: ell

นอกจากนี้คุณยังสามารถใช้ตัวแปรที่ถือความยาวเช่น: x=8; echo ${word:0:$x}แทนการเข้ารหัสจำนวนเต็มอย่างหนัก
Cometsong

1

นี่คือพกพา:

a="$(command)"             # Get the output of the command.
b="????"                   # as many ? as characters are needed.
echo ${a%"${a#${b}}"}      # select that many chars from $a

เพื่อสร้างสตริงของตัวแปรความยาวของตัวอักษรมีคำถามของตัวเองที่นี่


0

ฉันมีปัญหานี้เมื่อสร้างไฟล์เช็คซัมด้วยตนเองในที่เก็บ Maven แต่น่าเสียดายที่cut -cพิมพ์ขึ้นบรรทัดใหม่เสมอในตอนท้ายของการส่งออก เพื่อระงับการที่ฉันใช้xxd:

command | xxd -l$BYTES | xxd -r

มันส่งออก$BYTESไบต์ที่แน่นอนเว้นแต่ว่าการcommandส่งออกของจะสั้นลงแล้วเอาท์พุทว่า


อีกวิธีหนึ่งในการขึ้นcutบรรทัดใหม่ของการต่อท้ายคือการ pip ลงใน:| tr -d '\n'
Cometsong
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.