ASCII文字を16進コードにマップするawkコマンドは機能しません。

ASCII文字を16進コードにマップするawkコマンドは機能しません。

私はawkを使用しようとしていますが、各ASCII文字を16進コードにマップする小さなプログラムを書くのが素晴らしいアイデアだと思いました。これが私がこれまでにしたことです:

文字列は次のとおりです

abshdfitiggwigiwjirjgiejrigjr

私はそれを単純に保ち、キャリッジリターンやタップなどを含めませんでした。

awkの-Fフラグを使用してフィールドとして識別できるように、これをコンマ区切りのファイルにダンプしました。

a,b,s,h,d,f,i,t,i,g,g,w,i,g,i,w,j,i,r,j,g,i,e,j,r,i,g,j,r,

同じファイルの16進ダンプで同じことをしました。

61,62,73,68,64,66,69,74,69,67,67,77,69,67,69,77,6a,69,72,6a,67,69,65,6a,72,69,67,6a,72,0a,

今、私はすべて同じNFを持っているので、より簡単になると思い、次のawkコマンドを試しました。

awk -F ',' '{for(i=1;i<NF;i++){sum[$i]=$i}} END {for(char in sum) { print char, sum[char]} } ' line.txt linebits.txt 

ここで、line.txt と linebits.txt は正しいファイルに対応します。

出力は次のとおりです。

62 62
h h
72 72
i i
0a 0a
64 64
73 73
j j
w w
65 65
74 74
66 66
67 67
77 77
68 68
a a
69 69
b b
6a 6a
d d
e e
r r
f f
s s
61 61
g g
t t

もちろんこれは意味があります。なぜなら sum[$i]=$i は単に sum[g]=g を実行していて、私が印刷する2つは同じだからです。

この出力が表示される理由はわかりますが、解決策がわかりません。

希望のファイルを指定できますか?標準入力のインデックスを取得できますか?クレイジーな音のように聞こえます。

私が望む出力は次のとおりです。

char - hex code
char - hex code
.....

答え1

あなたの目標は、単に他の答えで簡単に取得できるASCIIテーブルを取得するのではなく、awkを学ぶことです。

これには入力ファイルは必要ありません。印刷可能なすべての文字を直接表示できます。

awk 'BEGIN{ for(i=32;i<127;i++) printf("%02x %c\n",i,i) }'

(これを行うと、同じように長い列が1つ生成されます。複数の列が必要な場合は練習のままにしてください。)

OTOH、2行のフィールドのペアを結合したい場合は、文字と16進数だけでなく、任意の値にすることができます。

awk [-Fasneeded] 'NR==1 { for(i=1;i<=NF;i++) save[i]=$i; next }
  { for(i=1;i<=NF;i++) print save[i],$i }' file ...
# linebreak for ease of reading, may be omitted in use

これは、2つの行が2つのファイル(あなたの場合のように)から出てくるか、1つのファイルから出てくるかにかかわらず機能します。行が3つ以上の場合、行1から各後続行までのフィールドはペアになります。このパターンは通常、行 1 にヘッダーがあり、各列の名前が続き、その後に変数の数が続く CSV タイプファイルに適しています。各列にデータがある行。

これは不正行為を含む順序も維持します。詐欺を取り除き、秩序を維持するには:

awk [-Fasneeded] 'NR==1 { for(i=1;i<=NF;i++) save[i]=$i; next } 
  { for(i=1;i<=NF;i++) if(!dupe[$i]++) print save[i],$i ;delete dupe }' file ...
# the delete dupe can be omitted in the two-line case

本当に欲しいなら、これによって生成されたランダムな順序もfor in可能ですが、私には理解できません。一部効果がある数字順やアルファベット順(重複を排除するため)などの順序が意味を持つことがあります。

答え2

より簡単な方法がありますが、ここでは目標はawkを学ぶようですので、説明する方法を使用して行う方法は次のとおりです。まず、私は,分離を使用しません。同様の作業を行うために線を使用する方が簡単です。その後、NR特殊変数を使用してFNR両方のファイルをリンクできます。NR現在の入力ライン番号を保存し、FNR入力ライン番号を保存します。現在読んでいるファイルの。したがってawk、それぞれ2行の2つのファイルが与えられた場合、ファイルはNRfromに移動します1が、42番目のファイルの最初の行を読み取るときはFNRfromに移動してから再び移動1します212

それらを組み合わせると、次のようになります。

## get the characters, one per line
printf '%s\n' {a..z} > chars

## get the 2byte codes as you had in the question. I am sure
## there is a simpler way, but this is the best I could come up with
hexdump -x chars | tr -s ' ' '\n' | sed -n 's/^0a//p' > codes

このファイルを使用して、次のことができます。

## Use awk to print them in pairs
$ awk '{ if(NR==FNR){chars[FNR]=$1} else{ print chars[FNR],$1}}' chars codes
a 61
b 62
c 63
d 64
e 65
f 66
g 67
h 68
i 69
j 6a
k 6b
l 6c
m 6d
n 6e
o 6f
p 70
q 71
r 72
s 73
t 74
u 75
v 76
w 77
x 78
y 79
z 7a

もちろん、以下を使用してこれを行うこともできますpaste

$ paste chars codes
a   61
b   62
c   63
d   64
e   65
f   66
g   67
h   68
i   69
j   6a
k   6b
l   6c
m   6d
n   6e
o   6f
p   70
q   71
r   72
s   73
t   74
u   75
v   76
w   77
x   78
y   79
z   7a

答え3

GNUを使用している場合は、awk拡張ライブラリを含めることができますordchr

echo abshdfitiggwigiwjirjgiejrigjr |
    awk -lordchr -F '' '{for(i=1;i<=NF;i++)printf "%c %x\n", $i, ord($i)}'
a 61
b 62
s 73
h 68
...

ord()-文字を10進数に変換する関数
printf "%x", ord($i)-10進数を16進数に変換
また: chr()-10進数を文字に変換

答え4

自分で書くのではなく、既存のプログラムを使うのはどうですか?私はお勧めしますasciiエリックS.レイモンドから。

上記のコマンドを使用してASCII文字の16進値を出力するには、次のコマンドを実行しますascii -x

出力例:

   00 NUL    10 DLE    20      30 0    40 @    50 P    60 `    70 p 
   01 SOH    11 DC1    21 !    31 1    41 A    51 Q    61 a    71 q 
   02 STX    12 DC2    22 "    32 2    42 B    52 R    62 b    72 r 
   03 ETX    13 DC3    23 #    33 3    43 C    53 S    63 c    73 s 
   04 EOT    14 DC4    24 $    34 4    44 D    54 T    64 d    74 t 
   05 ENQ    15 NAK    25 %    35 5    45 E    55 U    65 e    75 u 
   06 ACK    16 SYN    26 &    36 6    46 F    56 V    66 f    76 v 
   07 BEL    17 ETB    27 '    37 7    47 G    57 W    67 g    77 w 
   08 BS     18 CAN    28 (    38 8    48 H    58 X    68 h    78 x 
   09 HT     19 EM     29 )    39 9    49 I    59 Y    69 i    79 y 
   0A LF     1A SUB    2A *    3A :    4A J    5A Z    6A j    7A z 
   0B VT     1B ESC    2B +    3B ;    4B K    5B [    6B k    7B { 
   0C FF     1C FS     2C ,    3C <    4C L    5C \    6C l    7C | 
   0D CR     1D GS     2D -    3D =    4D M    5D ]    6D m    7D } 
   0E SO     1E RS     2E .    3E >    4E N    5E ^    6E n    7E ~ 
   0F SI     1F US     2F /    3F ?    4F O    5F _    6F o    7F DEL

関連情報