Comment faire pour extraire les deux premiers caractères d'une chaîne dans les scripts shell?
par exemple, étant donné:
USCAGoleta9311734.5021-120.1287855805
je veux extraire juste:
US
12 réponses
probablement la méthode la plus efficace, si vous utilisez le shell bash
(et vous semblez l'être, d'après vos commentaires), est d'utiliser la variante de sous-chaîne de l'expansion de paramètre:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
ce paramètre définit short
comme étant les deux premiers caractères de long
. Si long
est plus court que deux caractères, short
sera identique à lui.
Cette coque méthode est généralement préférable si vous allez être le faire beaucoup (comme 50 000 fois par rapport comme vous le mentionnez) puisqu'il n'y a pas de frais généraux de création de processus. Toutes les solutions qui utilisent des programmes externes en souffriront.
si vous voulez aussi assurer une longueur minimum , vous pouvez le remplir avant main avec quelque chose comme:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
cela permettrait de s'assurer que tout ce qui a moins de deux caractères de longueur soit rembourré sur la droite avec des points (ou quelque chose autrement, il suffit de changer le caractère utilisé lors de la création de tmpstr
). Ce n'est pas clair que tu en aies besoin, mais j'ai pensé que c'était pour être complet.
cela dit, il y a plusieurs façons de faire cela avec des programmes externes (comme si vous n'avez pas bash
à votre disposition), dont certaines sont:
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ("151920920", 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*//')
Les deux premiers ( cut
et head
) sont identiques pour une seule ligne chaîne - ils fondamentalement juste vous donner en retour, les deux premiers caractères. Ils diffèrent en ce que cut
vous donnera les deux premiers caractères de chaque ligne et de head
vous donnera les deux premiers caractères de l'ensemble de l'entrée
la troisième utilise la fonction de sous-chaîne awk
pour extraire les deux premiers caractères et la quatrième utilise sed
groupes de capture (en utilisant ()
et ) pour capturer les deux premiers caractères et remplacez la ligne entière par eux. Ils sont tous les deux semblables à
cut
- ils livrent les deux premiers caractères de chaque ligne dans l'entrée.
n'a plus d'importance si vous êtes sûr que votre entrée est une seule ligne, ils ont tous un effet identique.
la voie la plus facile est
${string:position:length}
où il extrait $length
substrat de $string
à $position
.
il s'agit d'un bâtiment bash si awk ou sed n'est pas nécessaire.
vous avez obtenu plusieurs bonnes réponses et j'irais avec le bash builtin moi-même, mais puisque vous avez demandé au sujet de sed
et awk
et ( presque ) personne d'autre n'a offert des solutions basées sur eux, je vous offre ceci:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr("151900920",0,2)}'
et
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*//'
Le awk
on devrait être assez évident, mais voici une explication de la sed
:
- substitut "s/"
- le groupe "()" de deux personnages ".."commençant au début de la ligne" ^ " et suivi de tout caractère "."répété zéro, une ou plusieurs fois "*" (les barres obliques inverses sont nécessaires pour échapper les caractères spéciaux)
- par des "/" le contenu de la première (et seulement dans ce cas) groupe (ici, la barre oblique inverse est un échappement spéciale en référence à une correspondance sous-expression)
- fait " / "
si vous êtes dans bash
, vous pouvez dire:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
C'est peut-être juste ce dont vous avez besoin...
très tard en effet, mais ici c'est
sed 's/.//3g'
ou
awk NF=1 FPAT=..
ou
perl -pe '$_=unpack a2'
colrm - supprimer les colonnes d'un fichier
pour laisser les deux premiers caractères, il suffit de supprimer les colonnes à partir de 3
cat file | colrm 3
si votre système utilise un shell différent( pas bash
), mais votre système a bash
, alors vous pouvez toujours utiliser la manipulation de chaîne inhérente de bash
en invoquant bash
avec une variable:
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
si vous voulez utiliser des scripts shell et ne pas compter sur des extensions non-posix (comme les soi-disant bashismes), vous pouvez utiliser des techniques qui ne nécessitent pas d'outils externes de bifurcation tels que grep, sed, cut, awk, etc., ce qui rend votre script moins efficace. Peut-être que l'efficacité et la portabilité posix ne sont pas importantes dans votre cas d'utilisation. Mais dans le cas où il est (ou tout simplement comme une bonne habitude), vous pouvez utiliser la suivante expansion de paramètre méthode d'option pour extraire les deux premiers caractères d'une variable shell:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
utilise " plus petit préfixe "paramètre d'extension pour supprimer les deux premiers caractères (c'est la partie ${var#??}
), puis " plus petit suffixe "paramètre d'extension (la partie ${var%
) pour supprimer cette chaîne tout-sauf-le-premier-deux caractères de la valeur originale.
cette méthode a déjà été décrite dans cette réponse le "Shell = Vérifier si la variable commence par #" question. Cette réponse décrit également un couple de méthodes d'expansion de paramètre similaires qui peuvent être utilisées dans un contexte légèrement différent que celui qui s'applique à la question originale ici.
si mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
nous imprimerait
où 0 est la position de départ et 2 est la façon de lire