J'ai un fichier texte de plus de 10 000 lignes. Dans ce fichier, j'ai un numéro de ligne 713 contenant trois nombres hexadécimaux comme, 7E 42 C0
. J'ai besoin de le convertir en décimal. Mon code fonctionne bien si je ne donne que ce numéro dans un fichier texte. Mais, je veux donner le fichier et le numéro de ligne de ce fichier
Comme dans ce qui suit:
while read p q r;
do
printf "%d %d %d\n" 0x$p 0x$q 0x$r;
done < $(sed -n '713p' run21.txt);
Mais cela n'a pas fonctionné et m'a donné une erreur de ambiguous redirect
. S'il vous plaît, faites-moi savoir une solution.
3 réponses
Vous êtes sur la bonne voie, pour passer de hex
à dec
utilisation bc
avec ibase
et obase
définis, par exemple
$ echo "obase=10; ibase=16; $(sed -n 713p run21.txt)" | bc
Quelle que soit la valeur hex
à la ligne 713
, elle sera affichée sous la forme decimal
. Vous pouvez utiliser read -r a b c
pour lire les 3 valeurs et les convertir chacune de manière similaire. Ou vous pouvez supprimer l'espace blanc entre les 3 valeurs hexadécimales et le convertir en une seule valeur décimale en fonction de vos besoins. Par exemple:
hexval=""
for i in $(sed -n 713p run21.txt); do
hexval="$hexval$i"
done
echo "obase=10; ibase=16; $hexval" | bc
Sortie
8274624
Pour convertir chacun séparément, vous pouvez faire:
for i in $(sed -n 713p run21.txt); do
printf " %d" "$(echo "obase=10; ibase=16; $i" | bc)"
done
printf "\n"
Sortie
126 66 192
Pour rendre la conversion plus robuste, vous pouvez (et devriez) ajouter une validation de toutes les valeurs lues en entrée. Vous pouvez faire beaucoup plus de validation quant au type de caractères lus dans chaque variable, mais vous devez au moins valider lire ET remplir le nombre de valeurs que vous attendiez. En mettant cela ensemble et en utilisant read
pour lire et valider les 3 valeurs, vous pouvez faire quelque chose comme ce qui suit.
Le script prend le line_to_read comme premier argument obligatoire et le filename
à lire comme son deuxième argument facultatif (il lira depuis stdin
par défaut):
#!/bin/bash
test -z "$1" && { ## validate line number given
printf "error: insufficient input.\nusage: %s line [file (stdin)]\n" "${0##*/}"
exit 1
}
test "$1" -eq "$1" &>/dev/null || { ## test $1 is an integer value
printf "error: first parameter not an integer '%s'\n" "$1"
exit 1
}
fn="$2" ## read from filename as 2nd parameter (or by default from stdin)
test -f "$fn" || fn=/dev/stdin
read -r a b c < <(sed -n "${1}p" "$fn") ## read each of the values
test -n "$a" -a -n "$b" -a -n "$c" || { ## validate all 3 vars filled
printf "error: less than 3 values on line '%s',\n" "$1"
exit 1
}
printf "input : %3x %3x %3x\n" "0x$a" "0x$b" "0x$c" ## output original line
## output line converted from hex to decimal
printf "output: %3d %3d %3d\n" $(echo "obase=10; ibase=16; $a" | bc) \
$(echo "obase=10; ibase=16; $b" | bc) $(echo "obase=10; ibase=16; $c" | bc)
Exemple d'entrée
$ cat dat/3hex.txt
7E 42 C0
Exemple d'utilisation / de sortie
$ bash 3hexcvt.sh 1 <dat/3hex.txt
input : 7e 42 c0
output: 126 66 192
@David j'ai fait ça
while read -r p q r;
do
#printf "%d %d %d\n" 0x$p 0x$q 0x$r;
#printf "%d %d %d\n"
echo "obase=10; ibase=16; $(sed -n 713p run21.txt)" | bc ;
done
Mais il n'y a pas de sortie.
Peut-être plus simple de cette façon ...
read p q r < <(sed -n '713{p;q}' file); printf "%d %d %d\n" 0x$p 0x$q 0x$r;
De nouvelles questions
linux
LES QUESTIONS LINUX DOIVENT ÊTRE LIÉES À LA PROGRAMMATION. Utilisez cette balise uniquement si votre question concerne la programmation à l'aide d'API Linux ou un comportement spécifique à Linux, et pas uniquement parce que vous exécutez votre code sous Linux. Si vous avez besoin d'une prise en charge Linux, vous pouvez essayer https://unix.stackexchange.com ou le site Stack Exchange de la distribution Linux spécifique comme https://askubuntu.com ou https://elementaryos.stackexchange.com/