Comment puis-je faire référence à une chaîne par index dans sh/bash? C'est-à-dire, le séparer essentiellement.
J'essaie de supprimer 5 caractères d'un nom de fichier. Tous les noms ont la structure: nom_nr_code. J'essaie de supprimer le bit de code alphanumérique 5. name_nr_
est toujours composé de 10 caractères.
Y a-t-il quelque chose comme;
for i in * ; do mv "$i" "$i"[:10] ; done
Aussi simple que cela.
(frapper)
for i in * ; do mv -- "$i" "${i:0:5}" ; done
Voila.
Et une explication de Advanced Bash-Scripting Guide ( Chapter 10. Manipulating Variables ), (with extra NOTEs en ligne pour souligner les erreurs dans ce manuel):
Extraction de sous-chaîne
${string:position}
Extrait la sous-chaîne de
$string
à$position
.Si la
$string
le paramètre est "*" ou "@", puis cela extrait les paramètres de position, en commençant à$position
.${string:position:length}
Extrait
$length
caractères de la sous-chaîne de$string
à$position
.
NOTE citations manquantes autour des extensions de paramètres! echo
ne doit pas être utilisé pour des données arbitraires.
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in ${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space "escape" the position parameter.
Les arguments position et length peuvent être "paramétrés", c'est-à-dire représentés comme une variable plutôt que comme une constante numérique.
Si la
$string
le paramètre est "*" ou "@", puis cela extrait un maximum de$length
paramètres de position, commençant à$position
.
echo ${*:2} # Echoes second and following positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters, starting at second.
NOTE: expr substr
est une extension GNU.
expr substr $string $position $length
Extrait
$length
caractères de$string
à partir de$position
.
stringZ=abcABC123ABCabc
# 123456789......
# 1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
NOTE: Ce echo
est redondant et le rend encore moins fiable. Utilisez expr substr + "$string1" 1 2
.
NOTE: expr
retournera avec un état de sortie non nul si la sortie est 0 (ou -0, 00 ...).
BTW. Le livre est présent dans le référentiel officiel d'Ubuntu en tant que abs-guide
.
Dans POSIX sh
,
"${var%?????}"
est $var
dépouillé des 5 derniers caractères de fin (ou $var
si $var
contient moins de 5 caractères)
"${var%"${var#??????????}"}"
correspond aux 10 premiers caractères de $var
.
"${var%_*}"
est $var
dépouillé de la chaîne la plus courte qui correspond à _*
au bout du $var
(foo_bar_baz
-> foo_bar
)."${var%%_*}"
: correspondance identique mais la plus longue au lieu de la correspondance la plus courte (foo_bar_baz
-> foo
).foo_bar_
: "${var%"${var##*_}"}"
(${var##pattern}
est le même que ${var%%pattern}
mais en cherchant le motif au début de $var
au lieu de la fin).Avec zsh
:
$var[1,-6]
pour le premier caractère au 6e depuis la fin (donc tous sauf les 5 derniers).$var[1,10]
pour les 10 premiers caractères.Avec ksh
, bash
ou zsh
:
"${var:0:10}"
: 10 premiers caractères de $var
Avec bash
ou zsh
:
"${var:0:-5}"
: tous sauf les 5 derniers caractères (donne une erreur et quitte le script si $var
est défini mais contient moins de 5 caractères, également lorsque $var
n'est pas défini avec zsh
).Si vous avez besoin de la compatibilité Bourne sh
, c'est très difficile à faire de manière fiable. Si vous pouvez garantir que le résultat ne se terminera pas par des caractères de nouvelle ligne, vous pouvez le faire:
first_10=`expr " $var" : ' \(.{1,10\}\)'` # beware the exit status
# may be non-zero if the
# result is 0 or 0000000000
all_but_last_5=`expr " $var" : ' \(.*\).\{5\}'`
Vous aurez également une limite sur la longueur de $var
(variant selon les systèmes).
Dans toutes ces solutions, si $var
contient des octets qui ne peuvent pas faire partie de caractères valides, YMMV.
sh
ne fournit pas un moyen intégré d'extraire une sous-chaîne d'une chaîne (pour autant que je sache), mais avec bash
vous pouvez le faire
${i:0:10}
Cela vous donnera les dix premiers caractères de la valeur de la variable i
.
Le format général est ${variable:offset:length}
.
La plupart des shells prennent en charge une sorte d'extension des paramètres qui peut vous aider. En bash, vous pouvez utiliser
substr=${string:4:5} # start at position 4, length 5.
Dans dash
, les décalages ne sont pas pris en charge, mais vous pouvez utiliser des modèles de début et de fin:
remove_first3=${string#???}
remove_last2=${string%??}
Tout d'abord, n'utilisez pas de boucle for
pour les noms de fichiers.
Ensuite, quelque chose comme ça devrait aider.
find ./ -type f | while read filename ;do
newfilename=$(echo ${filename}|cut -c 1-10)
mv ${filename} ${newfilename}
done