echo $ ((2 # $ 1)) ทำอะไรกันแน่


53

สคริปต์ทุบตีต่อไปนี้แสดงจำนวนทศนิยมเมื่อได้รับเลขฐานสอง

echo $((2#$1))

ทำไมล่ะ

ฉันเข้าใจว่า$1เป็นอินพุต อาจ2เป็นฐาน (ไบนารี) แต่ฉันไม่เข้าใจไวยากรณ์ที่ใช้

คำตอบ:


72

ผู้ชายทุบตี

   echo [-neE] [arg ...]
          Output  the  args,  separated  by spaces, followed by a newline.
          The return status is 0 unless a write error occurs.   If  -n  is
          specified, the trailing newline is suppressed.  If the -e option
          is given,  interpretation  of  the  following  backslash-escaped
          characters  is  enabled.

[ ... ]

   Arithmetic Expansion
       Arithmetic  expansion allows the evaluation of an arithmetic expression
       and the substitution of the result.  The format for  arithmetic  expan‐
       sion is:

              $((expression))

[ ... ]

   Constants with a leading 0 are interpreted as octal numbers.  A leading
   0x or  0X  denotes  hexadecimal.   Otherwise,  numbers  take  the  form
   [base#]n,  where the optional base is a decimal number between 2 and 64
   representing the arithmetic base, and n is a number in that  base.   If
   base#  is omitted, then base 10 is used.  When specifying n, the digits
   greater than 9 are represented by the lowercase letters, the  uppercase
   letters, @, and _, in that order.  If base is less than or equal to 36,
   lowercase and uppercase letters may be used interchangeably  to  repre‐
   sent numbers between 10 and 35.

66
-1 สำหรับคำอธิบายเป็นศูนย์
Max Ried

27
มันค่อนข้างอธิบายได้ดีที่ฉันคิดว่า
NanoPish

19
ตอบคำถามอย่างเต็มที่แม้ว่า "เพียง" โดยการแก้ไขเอกสารที่มีอยู่แล้วไม่ควรได้รับ -1 สำหรับฉัน โดยเฉพาะอย่างยิ่งถ้าเอกสารนั้นเป็น manpage ของ bash
YoungFrog

31
man bash | wcระบุว่าหน้า man [ทุบตี GNU รุ่น 3.2.57] เป็น 4890 บรรทัด, 37094 คำ , 329778 ตัวอักษร คำตอบนี้จะตัดเฉพาะบรรทัดที่มีความยาว 7 บรรทัด, 176 คำ , 1115 ตัวอักษรที่เกี่ยวข้อง ฉันคิดว่าคำตอบที่สมควรได้รับ upvote ของคุณ (เช่นเดียวกับความคิดเห็นนี้ ;-)
Bruno Bronosky

7
@MaxRied: -1 ถึงความคิดเห็นของคุณสำหรับการค้นหาที่ไม่จำเป็นปุย
Mehrdad

30

จาก Doc ที่: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

ค่าคงที่ที่มี 0 นำหน้าจะถูกตีความเป็นตัวเลขฐานแปด เครื่องหมายนำหน้า '0x' หรือ '0X' หมายถึงเลขฐานสิบหก มิฉะนั้นตัวเลขจะอยู่ในรูปแบบ [base #] n โดยที่ตัวเลือกพื้นฐานคือตัวเลขทศนิยมระหว่าง 2 ถึง 64 ที่แสดงถึงฐานเลขคณิตและ n คือตัวเลขในฐานนั้น หากไม่ระบุ base # ระบบจะใช้ฐาน 10 เมื่อระบุ n ตัวเลขที่มากกว่า 9 จะถูกแสดงด้วยตัวอักษรตัวพิมพ์เล็กตัวอักษรตัวพิมพ์ใหญ่ '@' และ '_' ตามลำดับนั้น หากฐานมีค่าน้อยกว่าหรือเท่ากับ 36 ตัวอักษรตัวพิมพ์เล็กและตัวพิมพ์ใหญ่อาจถูกนำมาใช้แทนกันเพื่อแสดงตัวเลขระหว่าง 10 และ 35

ดังนั้นecho $((16#FF))เอาท์พุท255และecho $((2#0110))เอาท์พุท6


25

คำตอบของ Iporนั้นยอดเยี่ยม แต่ไม่ค่อยสมบูรณ์นัก ส่วนที่ยกมาของหน้าคนทุบตีระบุว่าไวยากรณ์ใช้งานได้เฉพาะสำหรับค่าคงที่และไม่คงที่ คุณควรถามว่ามันใช้งานได้จริง ![base#]n2#$1

การขยาย

    การขยายจะดำเนินการในบรรทัดคำสั่งหลังจากที่มันถูกแบ่งออกเป็นคำ ดำเนินการขยายเจ็ดชนิด: การขยายรั้ง, การขยายตัวหนอน, พารามิเตอร์และการขยายตัวแปร, การทดแทนคำสั่ง, การขยายตัวทางคณิตศาสตร์, การแยกคำและการขยายชื่อพา ธ

    คำสั่งของการขยายคือ: การขยายรั้ง; การขยายตัวของลูกอัลเดอร์พารามิเตอร์และการขยายตัวแปรการขยายเลขคณิตและการทดแทนคำสั่ง (ทำได้จากซ้ายไปขวา) การแยกคำ และการขยายชื่อพา ธ

โดยพื้นฐานแล้ว Bash กำลังทำการทดแทนตัวแปรก่อนเพื่อให้$1แทนที่ด้วยค่าแรก จากนั้นจะทำการขยายเลขคณิตซึ่งเห็นค่าคงที่ที่เหมาะสมเท่านั้น


ดูเหมือนว่าไม่จำเป็น OP กล่าวว่า "ฉันเข้าใจว่า$1เป็นอินพุต"
สกอตต์

8
+1 เนื่องจากการเข้าใจลำดับของการขยายนั้นมีประโยชน์มากสำหรับการทำให้สำนวนของ Bash แตกต่างกัน
Anthony G - ความยุติธรรมสำหรับโมนิก้า

1
นี่อาจเป็นเพียงความเห็นต่อคำตอบของ Ipor
chepner

1
@chepner โปรดพยายามบีบข้อความบล็อกที่มีรูปแบบที่ดีให้เป็นความคิดเห็น :-)
Alexander

1
"โปรดทราบว่าพารามิเตอร์$1ถูกขยายเพื่อสร้างค่าคงที่จำนวนเต็มก่อนที่จะประเมินนิพจน์ทางคณิตศาสตร์ดูที่gnu.org/software/bash/manual/bash.txtส่วนที่ 3.5"
chepner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.