私はawk
テキストファイルを解析するために使用します。テキストファイルには、次の4バイトのデータフィールドがあります。
11110000 10100000 10110000 10010000
このフィールドを読み、2進数から16進数に変換したいと思います。現在私は10進数にprintf %x
なり、11110000
16進数になります。これが示す値ではありませ1111000
ん。0xA98760
0xF0
私のコードはシンプルで、BASHとLinuxを初めて使用します。
awk'{printf(%x %x %x %x, $1, $2, $3, $4)};
文字列フィールドをバイナリとして保存してから16進数に変換するには? "bc <<<"obase=16;ibase=2; を使用して端末から 16 進数を取得できます。 $変数""。このスクリプトを作成しようとすると構文エラーが発生します。
答え1
awk
10進数、8進数、16進数のみサポートされ、2進数はサポートされていません。あなたが使用できるperl
:
perl -lane 'BEGIN{$, = " "} print unpack "(H2)*", pack("(B8)4", @F)'
dc
GNUの場合tac
(一部のシステムも参照tail -r
):
{ echo 16o2i; cat; echo f; } < file.txt | dc | tac
使用(構文エラーがbc
// /の最新バージョンではなく、シェルで使用されている演算子に関連していると仮定)<<<
zsh
zsh
bash
ksh93
mksh
yash
{ echo 'obase=16; ibase=2'; tr -cs 01 '[\n*]'; } < file.txt | bc
答え2
これはエレガントではないハッキングですが、動作します。数値のバイナリ表現を取り、10進値を返す関数bを宣言します。その後、%xを使用してprintf
16進数で表されます。
$ awk 'func b(i, t,a,c){a=1;for(c=length(i);c>0;c--){t+=substr(i,c,1)=="1"?a:0;a*=2}return t}{printf "0x%x 0x%x 0x%x 0x%x\n",b($1),b($2),b($3),b($4)}' bin.txt
0xf0 0xa0 0xb0 0x90
答え3
perl -pale '$_ = join $", map { sprintf "%X", oct "0b$_" } @F'
簡単に:
Perl options: -p => autoprint + implcit file read in/line, a.la., awk -a => autosplit line into fields using default delimiter ' ' -l => ORS=IRS="\n" Perl standard variables: $" => list separator, by default it is a single space " " $_ => refers to the whole line, equivalent to $0 in awk @F => fields got by splitting the current line, $1, $2,$3, ... $NF in awk Perl code: map { body } list_of_items Map takes in an input list and applies the code present in it's body on each element of this list to generate an output list.
join <separator>, <list>
Join takes in an input list and joins their elements by the
separator provided in the first argument.
oct <number>
When the input to this function is prefixed by a "0b", then
it is treated to be a binary number and outputs the decimal
equivalent.
sprintf "%x" <decimal>
This function whose format is "%x" treats the input as
decimal and returns the equivalent number in hex.
答え4
ターゲットシステムにGNU Bashがある場合は、算術式で8進数と16進数以外の進数のサポートを利用できます。たとえば、
bash$ echo $(( 2#1011 | 2#1100 )) # bitwise OR of 11 and 12
15
さて、このデータを取得したら:
11110000 10100000 10110000 10010000
そして何とかこの文法に合わせて評価してみてください。
$(( 2#11110000101000001011000010010000 ))
我々は価値を得た
4037062800
(はい、これは32ビットbashバージョンで動作し、否定的な結果は得られません。)
私達はこれを非常に簡単にできます:
echo $(( 2#$(tr -d ' ' < file) ))
4037062800
唯一の問題は、すべてがeval
何らかの方法で偽装されているということです。ファイルの内容に基づいてコマンドの出力を式に挿入して評価します。file
信頼できないソースから入手した場合、セキュリティ上のリスクがある可能性があります。たとえば、私はfile
インターネットユーザーが送信したフォームのPOSTデータを含むApacheのCGIスクリプトにそれを入れません。