web-dev-qa-db-fra.com

Comment "déposer" / Supprimer des caractères de devant une chaîne?

J'ai une chaîne que je voudrais manipuler. La chaîne est H08W2345678 Comment puis-je pouvoir le manipuler afin que la sortie est juste W2345678?

De même si le je voulais laisser tomber les 4 derniers caractères de H08W2345678 Pour que je reçois H08W234 Comment ferais-je cela?

13
3kstc
$ echo "H08W2345678" | sed 's/^.\{3\}//'
W2345678

sed 's/^.\{3\}//' trouvera les trois premiers caractères de ^.\{3\} et remplacer par blanc. Ici ^. correspondra à n'importe quel caractère au début de la chaîne (^ indique le début de la chaîne) et \{3\} correspondra au modèle précédent exactement 3 fois. Donc, ^.\{3\} correspondra aux trois premiers caractères.

$ echo "H08W2345678" | sed 's/.\{4\}$//'
H08W234

De la même manière, sed 's/.\{4\}$//' remplacera les quatre derniers caractères par blanc ($ indique la fin de la chaîne).

8
heemayl

Si vous avez un fichier dans lequel chaque ligne est une chaîne de onze caractères (ou autre) que vous souhaitez couper, sed est l'outil à utiliser. C'est bien pour manipuler une seule chaîne, mais c'est surchargé. Pour une seule chaîne, la réponse de Jason est probablement le meilleur, si vous avez accès à Bash version 4.2 ou plus. Cependant, le ${parameter:offset} et ${parameter:offset:length} Les syntaxes semblent être uniques à Bash (puits, bash, ksh93, mksh et zsh) - je ne les vois pas dans les spécifications de base du groupe ouvert pour la langue de la commande shell . Si vous êtes coincé avec une coquille compatible POSIX qui ne prend pas en charge l'expansion de la sous-chaîne (extraction), vous pouvez utiliser

$ printf "%s\n" "${string#???}"
W2345678

$ printf "%s\n" "${string%????}"
H08W234

en utilisant printf au lieu de echo pour protéger les cordes comme abc-e, où, lorsque vous laissez tomber les trois premiers caractères, vous êtes laissé avec -e (et echo -e ne fait pas ce que vous voudriez).

Et si vous n'utilisez pas de coquille de la famille Bourne (ou si vous utilisez un système antique pré-posologique), celles-ci devraient toujours fonctionner:

$ expr " $string" : ' ...\(.*\)'
W2345678

$ expr " $string" : ' \(.*\)....'
H08W234

L'espace supplémentaire principal est d'éviter des problèmes de valeurs de $string qui sont réels expr opérateurs (par exemple, +, /, index ou match) ou options (par exemple, --, --help ou --version).

2
Scott

Avec:

string="H08W2345678"

Correspondant à 3 ou 4 caractères semble simple (pour la plupart des coquilles):

$ printf '%s\t%s\n' "${string#???}" "${string%????}"
W2345678      H08W234

Pour les coquilles plus anciennes (comme la coquille de Bourne), utilisez:

$ string=H08W2345678

$ expr " ${string}" : " ...\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\)...." '
H08W234

S'il est nécessaire un nombre numérique de caractères, utilisez:

$ expr " ${string}" : " .\{3\}\(.*\)"
W2345678

$ expr " ${string}" : " \(.*\).\{4\}" '
H08W234

Bien sûr, ces regex travaillent également avec SED, Awk et Bash 3.0+:

$ echo "$string" | sed 's/^.\{3\}//'
W2345678

$ echo "$string" | sed 's/.\{4\}$//'
H08W234

$ echo "$string" | awk '{sub(/^.{3}/,"")}1'
W2345678

$ echo "$string" | awk '{sub(/.{4}$/,"")}1'
H08W234

$ r='^.{3}(.*)$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
W2345678

$ r='^(.*).{4}$'; [[ $a =~ $r ]] && echo "${BASH_REMATCH[1]}"
H08W234
0
Isaac