web-dev-qa-db-ja.com

テキストファイルの10進数値のリストを16進形式に変換します

テキストファイルの10進数値のリストを16進形式に変換する必要があるので、たとえばtest.txtには次のものが含まれます。

131072
196608
262144
327680
393216
...

出力は、16進値のリスト(16進8桁、先行ゼロ付き)である必要があります。

00020000
00030000
00040000
...

出力はテキストファイルに出力されます。 pythonまたはLinuxシェルスクリプトでこれを作成する方法は?

編集#1

余分な操作を1つ逃しました。作成された16進値のそれぞれに80000000 hexを追加する必要があります。 (算術加算、すでに作成された16進値のリストに適用されます)。

3
minto

これは、printfおよびbashを使用して行うことができます。

printf '%08x\n' $(< test.txt)

または、printfとbcを使用して...ただ...

printf '%08s\n' $(bc <<<"obase=16; $(< test.txt)")

出力をテキストファイルに出力するには、シェルリダイレクト>を次のように使用します。

printf '%08x\n' $(< test.txt) > output.txt
11
jesse_b

3つの可能な解決策(各行がonly桁のセットであると想定):

Ksh、bash、zshなどのシェルの場合:

_printf '%08x\n' $(<infile)
_

Bashのみ

_<file.txt mapfile -t arr;   printf '%08x\n' "${arr[@]}" 
_

より単純なシェルの場合:ダッシュ(Debianベースのシステムではデフォルトのsh)、ash(ビジーボックスはエミュレートされたシェル)、yash、およびAIXとSolarisのデフォルトのシェル:

_printf '%08x\n' $(cat infile)
_

実際、家宝バージョン(Bourneのような)のようなシェルの場合、次のように記述する必要があります(上記のすべてのposixシェルで機能しますが、使用しないでください)。

_$ printf '%08x\n' `cat infile`
_

編集#1への回答

16進値_80000000_が32ビットコンピュータでオーバーフローを引き起こすことを理解してください(今日では一般的ではありませんが、可能です)。 echo "$((0x80000000))"が負の値を出力しないことを確認します。

_$ for i in $(<infile); do printf '%08x\n' "$(($i+0x80000000))"; done
80020000
80030000
80040000
80050000
80060000
_
5
Isaac

awkの使用:

$ awk '/[0-9]/ { printf("%08x\n", $0) }' file
00020000
00030000
00040000
00050000
00060000
4
Kusalananda

Juliaの使用

_$ Julia -e 'function hexadd(x) hex(( x + 0x80000000),8) end ; output = open("output.txt","w") ; open("test.txt") do inputfile for num in eachline(inputfile) write(output,"$(hexadd(parse(Int,num)))\n") end end'
_

複数行を読みやすくする必要があります。

_function hexadd(x)
    hex(( x + 0x80000000),8)
end
output = open("output.txt","w")
open("test.txt") do inputfile
    for num in eachline(inputfile)
        write(output,"$(hexadd(parse(Int,num)))\n")
    end
end
_
  • hex( value, pad)は値を16進数に変換し、必要に応じてパディングを追加します。
    hexaddは入力として整数を必要とするため、parse(Int,"string")を使用して文字列(eachlineの出力)をIntに変換し、それを関数で使用します。
  • _Julia -e_は式を評価します。
  • JuliaはFedora、ubuntuにネイティブにインストールできます

Dcの使用:

_$ dc -f test.txt -e '16o16i[80000000+psaz1<r]dsrx80000000+p' > output.txt
_

説明:

  • _dc -f test.txt -e '16o 16i [80000000 + p sa z 1 <r] sr z 1 <r 80000000 + p' > output.txt_
  • _-f file_ファイルの内容をスタックにプッシュします
  • _-e_式を実行
  • _16o_出力をbase 16に変換
  • _16i_は、ベース16での入力を想定しています。これは、ファイルの読み取り後に発生するため、ファイルはベース10で読み取られました。より明確に、_dc -e '10i' -f file -e '16 i 8000000'_
  • _[...]_文字列をスタックにプッシュします。この文字列はマクロとして使用されます。
  • _80000000 +_現在のスタックのトップと16進数80000000を追加します。結果をスタックのトップにプッシュします。
  • pポップせずに現在のスタックの先頭を出力します改行を印刷する印刷オプションのみ。
  • saスタックのトップをポップしてレジスタ 'a'に格納します。袋の上部を取り除くための方法にすぎません。
  • z現在のスタックの最上位はスタックの深さを持っています。再帰呼び出しを終了するために必要です。
  • _1_ 1をスタックの一番上にプッシュします。以前にプッシュされたスタック深度(z)と比較すると便利です。
  • _<r_スタックの2つの値を比較し、2番目が1番目より小さい場合は、レジスタ「r」を実行します。実際には、スタックの深さと「1」を比較します。
  • srポップしてレジスタ 'r'に格納します。これで、マクロはレジスタ「r」にあり、スタックの深さが1より大きい限り実行されます。ただし、まだ呼び出されていないものを除きます。
  • dスタックの上部とプッシュを複製します。
  • xスタックのトップをマクロとして実行します。
  • _d sr x_マクロとプッシュが重複しています。スタックには2つのコピーがあり、トップコピーをポップして保存し、登録し、2番目のコピーをポップして実行します...
  • したがって、スタック深度と1をプッシュし、比較して実行し、最後の要素について、16進数値を再度追加して出力します。
2
Dani_l

さらに別のワンライナー。まだpythonではありませんが、コメント、空行、およびファイル内のすべてを許可し、数字のみを含む行の結果のみを出力します。

Perl -ne '/^(\d+)$/ && printf "%08x\n", $1'  $your_file

次のようなファイルがあるとします。

$ cat $your_file
# some numbers,
131072
196608

262144
327680
393216

and empty lines
and whatever...

印刷する

00020000
00030000
00040000
00050000
00060000
2
mivk

Awkを使用できます ベロアライブラリ

$ velour '{print n_baseconv($0, 10, 16)}' test.txt
20000
30000
40000
50000
60000
0
Steven Penny