web-dev-qa-db-fra.com

Commande Linux (comme cat) pour lire un nombre spécifié de caractères

Existe-t-il une commande telle que cat dans Linux qui puisse renvoyer une quantité spécifiée de caractères d'un fichier?

par exemple, j'ai un fichier texte comme:

Hello world
this is the second line
this is the third line

Et je veux quelque chose qui rendrait les 5 premiers caractères, ce qui serait "bonjour".

merci

93
pbreault

head fonctionne aussi:

head -c 100 file  # returns the first 100 bytes in the file

..will extraire les 100 premiers octets et les renvoyer. 

Ce qui est bien dans l'utilisation de head pour cela, c'est que la syntaxe de tail correspond

tail -c 100 file  # returns the last 100 bytes in the file
156
Dan

Vous pouvez utiliser dd pour extraire des fragments d’octets arbitraires. 

Par exemple,

dd skip=1234 count=5 bs=1

copierait les octets 1235 à 1239 de son entrée à sa sortie et rejeterait le reste.

Pour obtenir les cinq premiers octets de l'entrée standard, procédez comme suit:

dd count=5 bs=1

Notez que, si vous voulez spécifier le nom du fichier d'entrée, dd a une analyse d'argument ancienne, vous ferez donc:

dd count=5 bs=1 if=filename

Notez aussi que dd annonce verbalement ce qu’il a fait, alors pour le jeter, faites:

dd count=5 bs=1 2>&-

ou

dd count=5 bs=1 2>/dev/null
42
fcw

tête :

Prénom

head - affiche la première partie des fichiers

Synopsis

tête [OPTION] ... [FICHIER] ...

La description

Imprimez les 10 premières lignes de chaque fichier sur la sortie standard. Avec plus d'un fichier, faites précéder chacun d'un en-tête donnant le nom du fichier. Sans FILE ou lorsque FILE est -, lisez l'entrée standard .

Les arguments obligatoires pour les options longues sont également obligatoires pour les options courtes .
-c--bytes=[-] N affiche les N premiers octets de chaque fichier; avec le '-' initial, affiche tous les N octets sauf les derniers de chaque fichier

11
gimel

la tête ou la queue peuvent aussi le faire:

tête -c X

Imprime les X premiers octets (pas nécessairement les caractères s'il s'agit d'un fichier UTF-16) du fichier. tail fera la même chose, à l'exception des X derniers octets.

Ceci (et coupé) sont portables.

3
Zathrus
head -Line_number file_name | tail -1 |cut -c Num_of_chars

ce script donne le nombre exact de caractères de la ligne et de l’emplacement spécifiques, par exemple: 

head -5 tst.txt | tail -1 |cut -c 5-8

donne les caractères de la ligne 5 et les caractères de 5 à 8 de la ligne 5, 

Remarque : tail -1 permet de sélectionner la dernière ligne affichée par la tête.

3
Vignesh

Je sais que la réponse est donnée à une question posée il y a 6 ans ...

Mais je cherchais quelque chose de similaire pendant quelques heures, puis j'ai découvert que: cut -c fait exactement cela, avec un bonus supplémentaire, à savoir que vous pouvez également spécifier un décalage.

cut -c 1-5 retournera Hello et cut -c 7-11 renverra world. Pas besoin d'aucune autre commande

2
bobbyus

vous pouvez également supprimer la ligne, puis la couper comme par exemple:

grep 'text' nomfichier | couper -c 1-5

2
nkr1pt

Bien que cette réponse ait été acceptée/acceptée il y a plusieurs années, la réponse actuellement acceptée n'est correcte que pour les codages à un octet par caractère tels que l'iso-8859-1, ou pour les sous-ensembles à un octet des jeux de caractères à octets variables (comme les caractères latins). dans UTF-8). Même en utilisant des épissures à plusieurs octets, cela ne fonctionnerait que pour les codages à octets fixes tels que UTF-16. Etant donné que UTF-8 est en passe de devenir une norme universelle, et lorsque vous regardez cette liste de langues par nombre de locuteurs natifs et cette liste des 30 langues les plus parlées par leur utilisation native/secondaire , il est important de souligner une technique simple, respectant les caractères (il ne s’agit pas d’octets), utilisant des octets variables, cut -c et tr/sed avec des classes de caractères.

Comparez les éléments suivants qui échouent deux fois en raison de deux erreurs/présomptions communes concernant les octets par rapport aux caractères (l'un est head contre cut, l'autre [a-z][A-Z] contre [:upper:][:lower:]):

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     head -c 1 | \
$     sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]

à ceci (note: cela fonctionnait bien sur FreeBSD, mais les versions cut et tr sous GNU/Linux étaient toujours modifiées en grec en UTF-8 pour moi):

$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$     cut -c 1 | \
$     tr '[:upper:]' '[:lower:]'
π

Une autre réponse plus récente avait déjà proposé "couper", mais uniquement à cause du problème secondaire suivant: il peut être utilisé pour spécifier des décalages arbitraires, et non à cause du problème de caractère directement opposé par rapport aux octets.

Si votre cut ne gère pas -c avec les codages sur octets variables correctement, pour "les premiers X caractères" (remplacez X par votre numéro), vous pouvez essayer:

  • sed -E -e '1 s/^(.{X}).*$/\1/' -e q - qui est limité à la première ligne si
  • head -n 1 | grep -E -o '^.{X}' - qui se limite à la première ligne et enchaîne deux commandes
  • dd - ce qui a déjà été suggéré dans d'autres réponses, mais est vraiment encombrant
  • Un script sed compliqué avec un tampon de fenêtre glissante pour gérer les caractères répartis sur plusieurs lignes, mais c'est probablement plus encombrant/fragile que d'utiliser simplement quelque chose comme dd

Si votre tr ne gère pas correctement les classes de caractères avec des codages à octets variables, vous pouvez essayer:

  • sed -E -e 's/[[:upper:]]/\L&/g (spécifique à GNU)
2
Rowan Thorpe

Voici un script simple qui utilise l'approche dd mentionnée ici:

extract_chars.sh

#!/usr/bin/env bash

function show_help()
{
  IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}

e.g. 

2 10 /tmp/it     => extract chars 2-10 from /tmp/it
EOF
  "
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`

if [ -z "$3" ]
then
  dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
  dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null 
fi
0
Brad Parks