วิธีการรับถ่านที่ตำแหน่งที่กำหนดของสตริงในเชลล์สคริปต์?
วิธีการรับถ่านที่ตำแหน่งที่กำหนดของสตริงในเชลล์สคริปต์?
คำตอบ:
ในทุบตีด้วย "การขยายพารามิเตอร์" $ $ พารามิเตอร์: ชดเชย: ความยาว}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
แก้ไข: ไม่ใช้การขยายพารามิเตอร์ (ไม่หรูหรามาก แต่นั่นคือสิ่งที่ฉันมาก่อน)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
echo ${var: -2:1}
zsh
mksh
ทางเลือกในการขยายพารามิเตอร์คือ expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
ตัวอย่างเช่น:
$ expr substr hello 2 1
e
substr
ไม่รวมอยู่ใน expr จาก FreeBSD, NetBSD หรือ OS X นี่ไม่ใช่โซลูชันแบบพกพา
substr
เดิมไม่ใช่ส่วนขยาย GNU การใช้งานดั้งเดิมexpr
มาจาก PWB Unix ในช่วงปลายยุค 70 และมีsubstr
(แต่ไม่ใช่:
)
cut -c
หากตัวแปรไม่มีการขึ้นบรรทัดใหม่คุณสามารถทำได้:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
เอาท์พุท:
b
awk substr
เป็นอีกทางเลือก POSIX ที่ใช้งานได้แม้ว่าตัวแปรจะมีบรรทัดใหม่:
myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
# the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"
เอาท์พุท:
b
printf '%s\n'
คือการหลีกเลี่ยงปัญหาเกี่ยวกับอักขระเลี่ยง: /programming//a/40423558/895245เช่น:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
ผลผลิต\
ตามที่คาดไว้
ดูเพิ่มเติมที่: /programming/1405611/extracting-first-two-characters-of-a-string-shell-scripting
ทดสอบใน Ubuntu 19.04
printf '%s' "$myvar" | cut -c2
ไม่ใช่ POSIX เนื่องจากเอาต์พุตของprintf
ไม่ใช่ข้อความเว้นแต่จะ$myvar
ลงท้ายด้วยอักขระขึ้นบรรทัดใหม่ มิฉะนั้นจะถือว่าตัวแปรไม่มีอักขระขึ้นบรรทัดใหม่ขณะcut
ตัดแต่ละบรรทัดของอินพุต
awk
หนึ่งจะมีประสิทธิภาพมากขึ้นและเชื่อถือได้กับawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
cut
ที่ใช้งานไม่ได้กับอักขระแบบหลายไบต์ (เหมือนกันสำหรับ mawk หรือ busybox awk)
printf 'abc '| cut -c2
ผิดเพราะไม่มี\n
(สิ่งนี้ฉันไม่รู้เกี่ยวกับ) หรือว่าคำสั่งจะล้มเหลวถ้า myvar มีบรรทัดใหม่ (ฉันเห็นด้วย)?
cut
ไม่ได้รับการระบุหากอินพุตไม่ใช่ข้อความ (แม้ว่าcut
การใช้งานจะต้องมีการจัดการกับเส้นหรือความยาวโดยพลการ) ผลลัพธ์ของprintf abc
ไม่ใช่ข้อความเนื่องจากไม่ได้ลงท้ายด้วยอักขระบรรทัดใหม่ ในทางปฏิบัติขึ้นอยู่กับการดำเนินการถ้าคุณท่อที่cut -c2
คุณจะได้รับอย่างใดอย่างหนึ่งb
, b<newline>
หรืออะไรเลย คุณจะต้องprintf 'abc\n' | cut -c2
ได้รับพฤติกรรมที่ระบุโดย POSIX (ที่จำเป็นในการส่งออกb<newline>
)
ด้วยzsh
หรือyash
คุณจะใช้:
$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*
(ในzsh
คุณสามารถย่อให้สั้นลงprintf '%s\n' $text[3]
)
คุณสามารถใช้คำสั่งตัด วิธีรับตำแหน่งที่ 3:
echo "SAMPLETEXT" | cut -c3
ตรวจสอบลิงค์นี้ได้ที่http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html
( กรณีขั้นสูง ) อย่างไรก็ตามการแก้ไข IFS ก็เป็นสิ่งที่ดีเช่นกันโดยเฉพาะเมื่ออินพุตของคุณอาจมีช่องว่าง ในกรณีนั้นเพียงอย่างเดียวให้ใช้อันด้านล่าง
saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs
IFS
จะเกิดอะไรขึ้นกับรหัสที่คุณโพสต์