Quel est le moyen le plus simple d'extraire la sous-chaîne sur une coquille UNIX (avec regex)?
Moyen simple:
Mise à jour
J'ai réalisé que la regex elle-même est conflictuelle avec la simplicité et j'ai choisi le plus simple cut
comme réponse choisie. Je suis désolé pour une vague question. J'ai changé de titre pour représenter plus précisément l'état actuel de ce QA.
cut
pourrait être utile:
$ echo hello | cut -c1,3
hl
$ echo hello | cut -c1-3
hel
$ echo hello | cut -c1-4
hell
$ echo hello | cut -c4-5
lo
Shell Construits sont bons pour cela aussi, voici un exemple de script:
#!/bin/bash
# Demonstrates shells built in ability to split stuff. Saves on
# using sed and awk in Shell scripts. Can help performance.
shopt -o nounset
declare -rx FILENAME=payroll_2007-06-12.txt
# Splits
declare -rx NAME_PORTION=${FILENAME%.*} # Left of .
declare -rx EXTENSION=${FILENAME#*.} # Right of .
declare -rx NAME=${NAME_PORTION%_*} # Left of _
declare -rx DATE=${NAME_PORTION#*_} # Right of _
declare -rx YEAR_MONTH=${DATE%-*} # Left of _
declare -rx YEAR=${YEAR_MONTH%-*} # Left of _
declare -rx MONTH=${YEAR_MONTH#*-} # Left of _
declare -rx DAY=${DATE##*-} # Left of _
clear
echo " Variable: (${FILENAME})"
echo " Filename: (${NAME_PORTION})"
echo " Extension: (${EXTENSION})"
echo " Name: (${NAME})"
echo " Date: (${DATE})"
echo "Year/Month: (${YEAR_MONTH})"
echo " Year: (${YEAR})"
echo " Month: (${MONTH})"
echo " Day: (${DAY})"
Qui sorties:
Variable: (payroll_2007-06-12.txt)
Filename: (payroll_2007-06-12)
Extension: (txt)
Name: (payroll)
Date: (2007-06-12)
Year/Month: (2007-06)
Year: (2007)
Month: (06)
Day: (12)
Et comme selon Gnudi ci-dessus, il y a toujours SED/AWK/PERL pour que la situation soit vraiment difficile.
Considérer aussi /usr/bin/expr
.
$ expr substr hello 2 3
ell
Vous pouvez également correspondre aux modèles contre le début des chaînes.
$ expr match hello h
1
$ expr match hello hell
4
$ expr match hello e
0
$ expr match hello 'h.*o'
5
$ expr match hello 'h.*l'
4
$ expr match hello 'h.*e'
2
Les coquilles UNIX ne disposent pas traditionnellement du support de regex intégré. Bash et ZSH font les deux, donc si vous utilisez le =~
Opérateur de comparer une chaîne à une regex, puis:
Vous pouvez obtenir les sous-chaînes du $BASH_REMATCH
Array dans Bash.
Dans ZSH, si le BASH_REMATCH
L'option Shell est définie, la valeur est dans le $BASH_REMATCH
Array, sinon c'est dans le $MATCH/$match
Paire de variables liées (un scalaire, l'autre un tableau). Si la RE_MATCH_PCRE
L'option est définie, puis le moteur PCRE est utilisé, sinon les bibliothèques système Regexp, pour une correspondance de la syntaxe Regexp étendue, selon Bash.
Donc, le plus simplement: si vous utilisez bash:
if [[ "$variable" =~ unquoted.*regex ]]; then
matched_portion="${BASH_REMATCH[0]}"
first_substring="${BASH_REMATCH[1]}"
fi
Si vous n'utilisez pas Bash ou ZSH, il devient plus compliqué car vous devez utiliser des commandes externes.
grep et SED sont probablement les outils que vous souhaitez, en fonction de la structure du texte.
sED devrait faire l'affaire, si vous ne savez pas ce que la sous-chaîne est, mais connaissez un modèle qui l'entoure.
par exemple, si vous souhaitez trouver une sous-chaîne de chiffres qui commence par un signe "#", vous pouvez écrire quelque chose comme:
sed 's/^.*#\([0-9]\+\)/\1/g' yourfile
gREP pourrait faire quelque chose de similaire, mais la question est de savoir ce que vous devez faire avec la sous-chaîne et si nous parlons du texte délimité de la ligne de ligne normale ou non.