Bash script เพื่อรับค่า ASCII สำหรับตัวอักษร


คำตอบ:


69

กำหนดฟังก์ชั่นทั้งสองนี้ (โดยปกติจะมีในภาษาอื่น):

chr() {
  [ "$1" -lt 256 ] || return 1
  printf "\\$(printf '%03o' "$1")"
}

ord() {
  LC_CTYPE=C printf '%d' "'$1"
}

การใช้งาน:

chr 65
A

ord A
65

7
@ dmsk80: +1 สำหรับคนอื่น ๆ อย่างผมที่คิดว่าพวกเขาจุดพิมพ์ผิด: "'A"ถูกต้องในขณะที่ถ้าคุณใช้มันจะพูดว่า:"A" A: invalid numberดูเหมือนว่ามันจะทำในด้าน printf (เช่นในเปลือก"'A"เป็น 2 ตัวอักษร, a 'และ a A. เหล่านั้นจะถูกส่งไปยัง printf และในบริบท printf ก็จะถูกแปลงเป็นค่า ASCII ของ A, และในที่สุดก็ถูกพิมพ์ เป็นทศนิยมขอบคุณ'%d'. ใช้'Ox%x'เพื่อแสดงใน hexa หรือ'0%o'ให้เป็นแปด))
Olivier Dulac

3
-1 ไม่ได้อธิบายวิธีการทำงาน ... ล้อเล่น: D, แต่อย่างจริงจังทำสิ่งเหล่านี้printf "\\$(printf '%03o' "$1")", '%03o', LC_CTYPE=Cและคำพูดเดียวใน"'$1"สิ่งที่ต้องทำ?
razzak

1
อ่านทั้งหมดรายละเอียดในคำถามที่พบบ่อย 71 การวิเคราะห์รายละเอียดที่ยอดเยี่ยม

19

คุณสามารถดูทั้งชุดด้วย:

$ man ascii

คุณจะได้รับตารางเป็นฐานแปดฐานสิบและทศนิยม


นอกจากนี้ยังมีแพ็คเกจ ascii สำหรับ distros แบบเดเบียน แต่ (อย่างน้อยตอนนี้) คำถามถูกแท็กเป็น bash ดังนั้นสิ่งเหล่านี้จะไม่ช่วย OP ในความเป็นจริงมันถูกติดตั้งในระบบของฉันและสิ่งที่ฉันได้รับจาก man ascii คือ man page ของมัน
โจ

12

หากคุณต้องการขยายเป็นอักขระ UTF-8:

$ perl -CA -le 'print ord shift' 😈
128520

$ perl -CS -le 'print chr shift' 128520
😈

ด้วยbash, kshหรือzshbuiltins:

$ printf "\U$(printf %08x 128520)\n"
😈

คุณตั้งใจจะใส่อักขระสี่เหลี่ยมจัตุรัสหรืออย่างอื่นอักขระถ่านดั้งเดิมจะไม่ถูกแสดงในโพสต์และจะถูกแทนที่ด้วยอักขระกล่องสี่เหลี่ยม
mtk

1
@mtk คุณต้องใช้เบราว์เซอร์ที่แสดง UTF-8 และแบบอักษรที่มีอักขระ128520ตัว
Stéphane Chazelas

ฉันใช้ Chrome ล่าสุดและไม่คิดว่ามันจะรองรับ UTF-8 ต้องการทราบว่าคุณเป็นเบราว์เซอร์ใด
mtk

@mtk, บนiceweasel Debian sidแบบอักษรที่ได้รับการยืนยันโดยเว็บคอนโซลของ iceweasel คือ "DejaVu Sans" และฉันได้รับ ttf-dejavu ttf-dejavu-core แพ็คเกจtt
dejavu

ฐานของ 128520 คืออะไร? ของตัวเองctbl()ดูเหมือนว่าจะถูกต้องช่วยให้ฉันไปแสดงและหั่นถ่านจากหัวของสตริงกับที่printfแต่มันทำให้4*((o1=360)>=(d1=240)|(o2=237)>=(d2=159)|(o3=230)>=(d3=152)|(o4=210)>=(d4=136))ใน$OPTARGค่าไบต์
mikeserv

12

มันใช้งานได้ดี

echo "A" | tr -d "\n" | od -An -t uC

echo "A"                              ### Emit a character.
         | tr -d "\n"                 ### Remove the "newline" character.
                      | od -An -t uC  ### Use od (octal dump) to print:
                                      ### -An  means Address none
                                      ### -t  select a type
                                      ###  u  type is unsigned decimal.
                                      ###  C  of size (one) char.

เทียบเท่ากับ:

echo -n "A" | od -An -tuC        ### Not all shells honor the '-n'.

3
คุณสามารถเพิ่มคำอธิบายเล็กน้อยได้ไหม?
แบร์นฮาร์ด

tr เพื่อลบ "\ n" (บรรทัดใหม่) ออกจากอินพุต od ถูกใช้เพื่อ -t dC คือการพิมพ์อักขระทศนิยม
Saravanan

1
echo -nระงับการขึ้นบรรทัดใหม่โดยไม่จำเป็นต้องใช้tr -d "\n"
Gowtham

2
@Gowtham เช่นเดียวกับการใช้งานบางอย่างechoไม่ได้อยู่ใน echos ที่สอดคล้องกับ Unix printf %s Aจะเป็นแบบพกพา
Stéphane Chazelas

6

ฉันกำลังหาวิธีแก้ปัญหา Bash ที่เรียบง่าย (และสง่างาม):

for i in {a..z}; do echo $(printf "%s %d" "$i" "'$i"); done

ในสคริปต์คุณสามารถใช้สิ่งต่อไปนี้:

CharValue="A"
AscValue=`printf "%d" "'$CharValue"

สังเกตคำพูดเดียวก่อน CharValue มันเป็นภาระผูกพัน ...


1
คำตอบของคุณแตกต่างจากคำตอบของ dsmsk80 อย่างไร
แบร์นฮาร์ด

1
การตีความคำถามของฉันคือ "วิธีรับค่า ASCII สำหรับค่าของตัวอักษร" ไม่ใช่วิธีการกำหนดฟังก์ชันเพื่อดึงค่า ASCII สำหรับหนึ่งอักขระ ดังนั้นคำตอบแรกของฉันคือคำสั่งหนึ่งบรรทัดสั้น ๆ เพื่อรับค่า ASCII สำหรับตัวอักษร
phulstaert

ฉันจะได้รับจุดของคุณ printf "%d"แต่ผมยังคิดว่าบรรทัดด้านล่างของคำตอบทั้งสอง
แบร์นฮาร์ด

2
ฉันยอมรับว่านี่เป็นส่วนสำคัญของกระบวนการเพื่อให้ได้ผลลัพธ์ แต่ฉันไม่ต้องการที่จะทำให้สมมติฐานที่ xmpirate รู้เกี่ยวกับ "for i in" และการใช้ช่วง หากเขาต้องการรายการสิ่งนี้อาจช่วยประหยัดเวลาได้จริง ;-) นอกจากนี้ผู้อ่านในอนาคตอาจพบว่าการเพิ่มของฉันเป็นประโยชน์
phulstaert

6
ctbl()  for O                   in      0 1 2 3
        do  for o               in      0 1 2 3 4 5 6 7
                do for  _o      in      7 6 5 4 3 2 1 0
                        do      case    $((_o=(_o+=O*100+o*10)?_o:200)) in
                                (*00|*77) set   "${1:+ \"}\\$_o${1:-\"}";;
                                (140|42)  set   '\\'"\\$_o$1"           ;;
                                (*)       set   "\\$_o$1"               ;esac
                        done;   printf   "$1";   shift
                done
        done
eval '
ctbl(){
        ${1:+":"}       return "$((OPTARG=0))"
        set     "" ""   "${1%"${1#?}"}"
        for     c in    ${a+"a=$a"} ${b+"b=$b"} ${c+"c=$c"}\
                        ${LC_ALL+"LC_ALL=$LC_ALL"}
        do      while   case  $c in     (*\'\''*) ;; (*) ! \
                                 set "" "${c%%=*}='\''${c#*=}$1'\'' $2" "$3"
                        esac;do  set    "'"'\''\${c##*\'}"'$@";  c=${c%\'\''*}
        done;   done;   LC_ALL=C a=$3 c=;set "" "$2 OPTARG='\''${#a}*("
        while   [ 0 -ne "${#a}" ]
        do      case $a in      ([[:print:][:cntrl:]]*)
                        case    $a in   (['"$(printf \\1-\\77)"']*)
                                        b=0;;   (*)     b=1
                        esac;;  (['"$(  printf  \\200-\\277)"']*)
                                        b=2;;   (*)     b=3
                esac;    set    '"$(ctbl)"'     "$@"
                eval "   set    \"\${$((b+1))%"'\''"${a%"${a#?}"}"*}" "$6"'\''
                a=${a#?};set    "$((b=b*100+${#1}+${#1}/8*2)))" \
                                "$2(o$((c+=1))=$b)>=(d$c=$((0$b)))|"
        done;   eval "   unset   LC_ALL  a b c;${2%?})'\''"
        return  "$((${OPTARG%%\**}-1))"
}'

ครั้งแรกctbl()- ที่ด้านบนสุด - วิ่งครั้งเดียวเท่านั้น มันสร้างผลลัพธ์ต่อไปนี้(ซึ่งถูกกรองผ่านsed -n lเพื่อประโยชน์ในการพิมพ์) :

ctbl | sed -n l

 "\200\001\002\003\004\005\006\a\b\t$
\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\
\035\036\037 !\\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRS\
TUVWXYZ[\\]^_\\`abcdefghijklmnopqrstuvwxyz{|}~\177" "\200\201\202\203\
\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\
\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\
\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\
\267\270\271\272\273\274\275\276\277" "\300\301\302\303\304\305\306\
\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\
\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\
\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\
\372\373\374\375\376\377"$

... ซึ่งทั้งหมด 8 บิต(น้อยกว่าNUL)แบ่งออกเป็นสี่สตริงที่ยกมาเชลล์แบ่งเท่า ๆ กันที่ขอบเขต 64- ไบต์ สตริงอาจจะเป็นตัวแทนที่มีช่วงฐานแปดเช่น\200\1-\77, \100-\177, \200-\277, \300-\377ที่ไบต์ 128 NULถูกใช้เป็นสถานที่สำหรับผู้ถือ

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

ครึ่งบนของctbl()ฟังก์ชั่นที่สองส่วนใหญ่เป็นอุปกรณ์เสริมที่นี่ - มันถูกออกแบบมาให้พกพาได้อย่างปลอดภัยและต่อเนื่องสถานะเชลล์ปัจจุบันใด ๆ ที่มันอาจส่งผลกระทบเมื่อมันถูกเรียก การวนรอบด้านบนจะอ้างอิงอัญประกาศใด ๆ ในค่าของตัวแปรใด ๆ ที่มันอาจต้องการใช้แล้วกองซ้อนผลลัพธ์ทั้งหมดในพารามิเตอร์ตำแหน่ง

แม้ว่าสองบรรทัดแรกจะส่งคืน 0 ทันทีก่อนและตั้งค่า$OPTARGเป็นเหมือนกันหากอาร์กิวเมนต์แรกของฟังก์ชันไม่มีอักขระอย่างน้อยหนึ่งตัว และถ้าเป็นเช่นนั้นบรรทัดที่สองจะตัดอาร์กิวเมนต์แรกเป็นอักขระตัวแรกทันทีเนื่องจากฟังก์ชันจัดการกับอักขระในแต่ละครั้งเท่านั้น ที่สำคัญมันทำสิ่งนี้ในบริบทสถานที่ปัจจุบันซึ่งหมายความว่าหากตัวละครอาจประกอบด้วยมากกว่าหนึ่งไบต์แล้วให้เปลือกให้ถูกต้องรองรับหลายไบต์ตัวอักษรมันจะไม่ทิ้งไบต์ใด ๆ ยกเว้นที่ไม่ได้อยู่ใน อักขระตัวแรกของอาร์กิวเมนต์แรก

        ${1:+":"}       return "$((OPTARG=0))"
        set     "" ""   "${1%"${1#?}"}"

จากนั้นทำการวนซ้ำการบันทึกหากจำเป็นและหลังจากนั้นจะกำหนดบริบทโลแคลปัจจุบันเป็นโลแคล C สำหรับทุกหมวดหมู่โดยกำหนดให้กับLC_ALLตัวแปร จากจุดนี้เป็นต้นไปอักขระสามารถประกอบด้วยไบต์เดียวเท่านั้นดังนั้นหากมีหลายไบต์ในอักขระตัวแรกของอาร์กิวเมนต์แรกตอนนี้อักขระเหล่านี้ควรสามารถระบุแอดเดรสแต่ละตัวเป็นอักขระแต่ละตัวในสิทธิของตนเอง

        LC_ALL=C

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

        while   [ 0 -ne "${#a}" ]
        do      case $a in      ([[:print:][:cntrl:]]*)
                        case    $a in   (['"$(printf \\1-\\77)"']*)
                                        b=0;;   (*)     b=1
                        esac;;  (['"$(  printf  \\200-\\277)"']*)
                                        b=2;;   (*)     b=3
                esac;    set    '"$(ctbl)"'     "$@"

โปรดทราบว่าการ$(ctbl)ทดแทนคำสั่งดังกล่าวจะถูกประเมินเพียงครั้งเดียว - โดยevalเมื่อฟังก์ชั่นมีการกำหนดเริ่มต้น - และตลอดไปหลังจากที่โทเค็นนั้นจะถูกแทนที่ด้วยผลลัพธ์ที่แท้จริงของการทดแทนคำสั่งนั้นเป็นบันทึกไว้ในหน่วยความจำของเชลล์ เช่นเดียวกับการcaseทดแทนคำสั่งทั้งสองรูปแบบ ฟังก์ชั่นนี้ไม่เคยเรียก subshell หรือคำสั่งอื่น ๆ มันจะยังไม่เคยพยายามที่จะอ่านหรือเขียนอินพุต / เอาต์พุต(ยกเว้นในกรณีของบางข้อความวินิจฉัยเปลือก - ซึ่งอาจบ่งชี้ข้อผิดพลาด)

โปรดทราบด้วยว่าการทดสอบความต่อเนื่องของวงไม่ได้เป็นเพียง[ -n "$a" ]เพราะฉันพบกับความยุ่งยากของฉันด้วยเหตุผลบางอย่างที่bashเชลล์ทำ:

char=$(printf \\1)
[ -n "$char" ] || echo but it\'s not null\!

but it's not null!

... และดังนั้นฉันอย่างชัดเจนเปรียบเทียบ$a's len 0 สำหรับแต่ละซ้ำซึ่งยังลึกลับทำงานแตกต่างกัน(อ่าน: ถูกต้อง)

caseตรวจสอบไบต์แรกเพื่อรวมไว้ในใด ๆ $bของสี่สายของเราและเก็บการอ้างอิงไปยังชุดไบต์ใน หลังจากนั้นพารามิเตอร์ตำแหน่งสี่ตัวแรกของเชลล์คือsetสตริงที่ฝังตัวevalและเขียนโดยctbl()รุ่นก่อน

ถัดไปสิ่งที่เหลืออยู่ของอาร์กิวเมนต์แรกจะถูกตัดทอนไปที่อักขระตัวแรกอีกครั้งชั่วคราวซึ่งตอนนี้ควรมั่นใจได้ว่าจะเป็นไบต์เดียว ไบต์แรกนี้ถูกใช้เป็นข้อมูลอ้างอิงเพื่อดึงแถบจากส่วนท้ายของสตริงที่จับคู่และการอ้างอิงใน$bคือeval'd เพื่อแสดงพารามิเตอร์ตำแหน่งดังนั้นทุกอย่างจากไบต์อ้างอิงถึงไบต์สุดท้ายในสตริงสามารถใช้แทนได้ สามสายอื่น ๆ จะถูกดรอปจากพารามิเตอร์ตำแหน่งทั้งหมด

               eval "   set    \"\${$((b+1))%"'\''"${a%"${a#?}"}"*}" "$6"'\''
               a=${a#?};set    "$((b=b*100+${#1}+${#1}/8*2)))" \
                                "$2(o$((c+=1))=$b)>=(d$c=$((0$b)))|"

ณ จุดนี้ค่าของไบต์(modulo 64)สามารถอ้างอิงเป็น len ของสตริงได้:

str=$(printf '\200\1\2\3\4\5\6\7')
ref=$(printf \\4)
str=${str%"$ref"*}
echo "${#str}"

4

คณิตศาสตร์เล็ก ๆ น้อย ๆ ที่จะทำแล้วจะคืนดีโมดูลัสขึ้นอยู่กับค่าใน$bไบต์แรกใน$aเป็นปล้นถาวรออกไปและเอาท์พุทสำหรับรอบปัจจุบันถูกผนวกเข้ากับสแต็คที่ค้างอยู่เสร็จสิ้นก่อนที่จะห่วงรีไซเคิลเพื่อตรวจสอบว่า$aเป็นจริงที่ว่างเปล่า

    eval "   unset   LC_ALL  a b c;${2%?})'\''"
    return  "$((${OPTARG%%\**}-1))"

เมื่อ$aว่างเปล่าแน่นอนชื่อและรัฐทั้งหมด - ยกเว้น$OPTARG- ว่าฟังก์ชั่นที่ได้รับผลกระทบตลอดระยะเวลาการดำเนินการของมันจะถูกเรียกคืนสู่สถานะก่อนหน้า - ไม่ว่าจะตั้งค่าและไม่เป็นโมฆะตั้งค่าและเป็นโมฆะ เพื่อ$OPTARGเป็นฟังก์ชันส่งคืน ค่าส่งคืนที่แท้จริงคือหนึ่งน้อยกว่าจำนวนไบต์ทั้งหมดในอักขระตัวแรกของอาร์กิวเมนต์แรกดังนั้นอักขระไบต์เดี่ยวใด ๆ จะคืนค่าศูนย์และอักขระหลายไบต์ใด ๆ จะส่งกลับมากกว่าศูนย์ - และรูปแบบผลลัพธ์จะแปลกเล็กน้อย

ค่าctbl()ประหยัดไป$OPTARGคือการแสดงออกเปลือกคณิตศาสตร์ที่ถูกต้องว่าถ้าประเมินจะตั้งพร้อมกันชื่อตัวแปรของรูปแบบ$o1, $d1, $o2, $d2ทศนิยมและค่าฐานแปดไบต์ที่เกี่ยวข้องทั้งหมดในตัวอักษรตัวแรกของการโต้แย้งครั้งแรก แต่ในท้ายที่สุดประเมินทั้งหมด จำนวนไบต์ในอาร์กิวเมนต์แรก ฉันมีกระบวนการทำงานที่เฉพาะเจาะจงในใจเมื่อเขียนสิ่งนี้และฉันคิดว่าอาจมีการสาธิตตามลำดับ

ฉันมักจะหาเหตุผลที่จะแยกสตริงด้วยgetoptsชอบ:

str=some\ string OPTIND=1
while   getopts : na  -"$str"
do      printf %s\\n "$OPTARG"
done

s
o
m
e

s
t
r
i
n
g

ฉันอาจจะทำมากกว่าพิมพ์เพียง char ต่อบรรทัด แต่สิ่งที่เป็นไปได้ ในกรณีใด ๆ ผมยังไม่ได้พบgetoptsว่าถูกต้องจะทำ(ตีว่า - dash's getoptsไม่ได้ถ่านจากถ่าน แต่bashแน่นอนไม่ได้) :

str=ŐőŒœŔŕŖŗŘřŚśŜŝŞş  OPTIND=1
while   getopts : na  -"$str"
do      printf %s\\n "$OPTARG"
done|   od -tc

0000000 305  \n 220  \n 305  \n 221  \n 305  \n 222  \n 305  \n 223  \n
0000020 305  \n 224  \n 305  \n 225  \n 305  \n 226  \n 305  \n 227  \n
0000040 305  \n 230  \n 305  \n 231  \n 305  \n 232  \n 305  \n 233  \n
0000060 305  \n 234  \n 305  \n 235  \n 305  \n 236  \n 305  \n 237  \n
0000100

ตกลง. ดังนั้นฉันพยายาม ...

str=ŐőŒœŔŕŖŗŘřŚśŜŝŞş
while   [ 0 -ne "${#str}" ]
do      printf %c\\n "$str"    #identical results for %.1s
        str=${str#?}
done|   od -tc

#dash
0000000 305  \n 220  \n 305  \n 221  \n 305  \n 222  \n 305  \n 223  \n
0000020 305  \n 224  \n 305  \n 225  \n 305  \n 226  \n 305  \n 227  \n
0000040 305  \n 230  \n 305  \n 231  \n 305  \n 232  \n 305  \n 233  \n
0000060 305  \n 234  \n 305  \n 235  \n 305  \n 236  \n 305  \n 237  \n
0000100

#bash
0000000 305  \n 305  \n 305  \n 305  \n 305  \n 305  \n 305  \n 305  \n
*
0000040

เวิร์กโฟลว์แบบนั้น - ไบต์สำหรับไบต์ / อักขระชนิดถ่าน - เป็นสิ่งที่ฉันมักจะได้รับเมื่อทำสิ่ง tty ที่ขอบนำเข้าคุณจำเป็นต้องรู้ค่าถ่านทันทีที่คุณอ่านและคุณต้องการขนาดของมัน(โดยเฉพาะเมื่อนับจำนวนคอลัมน์)และคุณต้องมีอักขระเป็นอักขระทั้งหมด

และตอนนี้ฉันมีctbl():

str=ŐőŒœŔŕŖŗŘřŚśŜŝŞş
while [ 0 -ne "${#str}" ]
do    ctbl "$str"
      printf "%.$(($OPTARG))s\t::\t$OPTARG\t::\t$?\t::\t\\$o1\\$o2\n" "$str"
      str=${str#?}
done

Ő   ::  2*((o1=305)>=(d1=197)|(o2=220)>=(d2=144))   ::  1   ::  Ő
ő   ::  2*((o1=305)>=(d1=197)|(o2=221)>=(d2=145))   ::  1   ::  ő
Œ   ::  2*((o1=305)>=(d1=197)|(o2=222)>=(d2=146))   ::  1   ::  Œ
œ   ::  2*((o1=305)>=(d1=197)|(o2=223)>=(d2=147))   ::  1   ::  œ
Ŕ   ::  2*((o1=305)>=(d1=197)|(o2=224)>=(d2=148))   ::  1   ::  Ŕ
ŕ   ::  2*((o1=305)>=(d1=197)|(o2=225)>=(d2=149))   ::  1   ::  ŕ
Ŗ   ::  2*((o1=305)>=(d1=197)|(o2=226)>=(d2=150))   ::  1   ::  Ŗ
ŗ   ::  2*((o1=305)>=(d1=197)|(o2=227)>=(d2=151))   ::  1   ::  ŗ
Ř   ::  2*((o1=305)>=(d1=197)|(o2=230)>=(d2=152))   ::  1   ::  Ř
ř   ::  2*((o1=305)>=(d1=197)|(o2=231)>=(d2=153))   ::  1   ::  ř
Ś   ::  2*((o1=305)>=(d1=197)|(o2=232)>=(d2=154))   ::  1   ::  Ś
ś   ::  2*((o1=305)>=(d1=197)|(o2=233)>=(d2=155))   ::  1   ::  ś
Ŝ   ::  2*((o1=305)>=(d1=197)|(o2=234)>=(d2=156))   ::  1   ::  Ŝ
ŝ   ::  2*((o1=305)>=(d1=197)|(o2=235)>=(d2=157))   ::  1   ::  ŝ
Ş   ::  2*((o1=305)>=(d1=197)|(o2=236)>=(d2=158))   ::  1   ::  Ş
ş   ::  2*((o1=305)>=(d1=197)|(o2=237)>=(d2=159))   ::  1   ::  ş

โปรดทราบว่าctbl()จริง ๆ แล้วไม่ได้กำหนด$[od][12...]ตัวแปร - มันไม่เคยมีผลกระทบยาวนานใด ๆ ในสถานะใด ๆ แต่$OPTARG- เพียงใส่สตริง$OPTARGที่สามารถใช้ในการกำหนดพวกเขา - ซึ่งเป็นวิธีที่ฉันได้รับสำเนาที่สองของแต่ละถ่านดังกล่าวข้างต้นโดยทำprintf "\\$o1\\$o2"เพราะ $(($OPTARG))พวกเขาจะตั้งในแต่ละครั้งที่ผมประเมิน แต่ที่ผมทำมันฉันยังประกาศปรับปรุงข้อมูลความยาวprintfของ%sรูปแบบการโต้แย้งสตริงและเพราะการแสดงออกมักจะประเมินจำนวนไบต์ในตัวละครที่ฉันได้รับตัวละครทั้งในการส่งออกเมื่อฉัน:

printf %.2s "$str"

คุณควรแข่งขันในการประกวดรหัสทุบตีที่สับสน!
HelloGoodbye

1
@HelloGoodbye นี้ไม่ได้เป็นรหัสทุบตี และสิ่งนี้ไม่ได้ทำให้งงงวย เพื่อดูความงงงวยโปรดดูที่ใน[ "$(printf \\1)" ]|| ! echo but its not null!ขณะเดียวกันอย่าลังเลที่จะทำความคุ้นเคยกับการฝึกฝนความคิดเห็นที่มีความหมายดีกว่าเว้นแต่คุณจะแนะนำการแข่งขันดังกล่าวจริง ... ?
mikeserv

ไม่ฉันไม่ได้สิ่งที่ฉันเขียนเป็นเพียงอีกวิธีหนึ่งในการบอกว่ารหัสของคุณสับสนมาก (อย่างน้อยสำหรับฉัน) แต่บางทีมันก็ไม่ควรที่จะเข้าใจได้ง่าย หากไม่ทุบตีแปลว่าเป็นภาษาอะไร
HelloGoodbye

@HelloGoodbye - นี่คือshภาษาคำสั่งPOSIX bashเป็นbourne supraset อีกครั้งเหมือนกันและในส่วนใหญ่ motipator สูงชันสำหรับมากของการดูแลจ่ายไปด้านบนแบบพกพาอย่างกว้างขวางขยายตัวเองและเนมสเปซขนาดตัวอักษรเกียรติทุกชนิด bashควรจัดการกับสิ่งนี้มากแล้ว แต่cภาษาprintfก็อาจจะขาดขีดความสามารถที่ให้ไว้ข้างต้น
mikeserv

ฉันยังอยากใช้ printf "% d" "$ char" เพื่อความเรียบง่ายและอ่านง่าย ฉันอยากรู้ว่าปัญหาแบบนี้ทำให้ฉันพบที่อยู่ของโซลูชัน @ mikeserv อะไร มีมากกว่าแค่ตัวควบคุมบางตัวที่ส่งผลต่อโค้ดส่งคืน (ซึ่งฉันเชื่อว่าเป็นประเด็นของเขาในความคิดเห็นด้านบน)?
Alex Jansen

3

ไม่ใช่เชลล์สคริปต์ แต่ใช้งานได้

awk 'BEGIN{for( i=97; i<=122;i++) printf "%c %d\n",i,i }'  

ตัวอย่างผลลัพธ์

xieerqi:$ awk 'BEGIN{for( i=97; i<=122;i++) printf "%c %d\n",i,i }' | head -n 5                                    
a 97
b 98
c 99
d 100
e 101

2
  • เลือกสัญลักษณ์จากนั้นกด CTRL + C
  • เปิด konsole
  • และประเภท: xxd<press enter>
  • จากนั้นกด <SHIFT+INSERT><CTRL+D>

คุณได้รับสิ่งที่ชอบ:

mariank@dd903c5n1 ~ $ xxd
û0000000: fb 

คุณรู้ว่าสัญลักษณ์ที่คุณวางมีรหัสฐานสิบหก 0xfb

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