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
87

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.

131
répondu paxdiablo 2017-06-29 01:38:44

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.

33
répondu ennuikiller 2013-04-19 01:19:58

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 " / "
30
répondu Dennis Williamson 2009-09-10 15:40:31

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...

5
répondu Dominic Mitchell 2009-09-10 16:35:06

Juste grep:

echo 'abcdef' | grep -Po "^.."        # ab
5
répondu Amir Mehler 2017-01-02 18:33:50

très tard en effet, mais ici c'est

sed 's/.//3g'

ou

awk NF=1 FPAT=..

ou

perl -pe '$_=unpack a2'
4
répondu Steven Penny 2015-07-02 12:45:31

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
3
répondu Ian Yang 2009-09-10 15:44:59

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;"
1
répondu palswim 2017-01-23 20:43:02

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.

1
répondu Juan 2018-03-25 22:42:56
perl -ple 's/^(..).*//'
0
répondu dsm 2009-09-10 14:44:53

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

0
répondu Jambobond 2013-04-19 01:20:37

c'est ce que vous voulez?

my $string = 'USCAGoleta9311734.5021-120.1287855805';

my $first_two_chars = substr $string, 0, 2;

ref: substr

0
répondu draegtun 2013-04-19 01:21:09