Comment puis-je faire référence à une chaîne par index dans sh / bash? Autrement dit, 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 de 10 caractères.
Y a-t-il quelque chose comme;
for i in * ; do mv "$i" "$i"[:10] ; done
bash
tag si vous demandez unesh
solution?Réponses:
Aussi simple que cela.
(frapper)
Voila.
Et une explication du Guide de Bash-Scripting Avancé ( Chapitre 10. Manipulation des Variables ) , (avec des NOTEs supplémentaires en ligne pour mettre en évidence les erreurs dans ce manuel):
NOTEcitations manquantes autour des extensions de paramètres!
echo
ne doit pas être utilisé pour des données arbitraires.NOTE:
expr substr
est une extension GNU.NOTE: C'est
echo
redondant et le rend encore moins fiable. Utilisezexpr 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 Ubuntu en tant que
abs-guide
.la source
${var:1}
cela ne renvoie pas la valeur devar
la "1ère position", mais en fait de la 2ème.Dans POSIX
sh
,"${var%?????}"
est$var
supprimé des 5 derniers caractères de fin (ou$var
s'il$var
contient moins de 5 caractères)"${var%"${var#??????????}"}"
est les 10 premiers caractères de$var
."${var%_*}"
est$var
supprimé de la chaîne la plus courte qui correspond_*
à la fin de$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}
c'est la même chose${var%%pattern}
mais en cherchant le motif au début$var
de la fin)Avec
zsh
:$var[1,-6]
pour le premier caractère au 6e de la fin (donc tous sauf les 5 derniers).$var[1,10]
pour les 10 premiers caractères.Avec
ksh
,bash
ouzsh
:"${var:0:10}"
: 10 premiers caractères de$var
Avec
bash
ouzsh
:"${var:0:-5}"
: tous sauf les 5 derniers caractères (donne une erreur et quitte le script s'il$var
est défini mais contient moins de 5 caractères, également lorsqu'il$var
n'est pas défini aveczsh
).Si vous avez besoin de la
sh
compatibilité Bourne , 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: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.la source
sh
ne fournit pas un moyen intégré d'extraire une sous-chaîne d'une chaîne (pour autant que je puisse voir), mais avecbash
vous, vous pouvez le faireCela vous donnera les dix premiers caractères de la valeur de la variable
i
.Le format général est
${variable:offset:length}
.la source
La plupart des shells prennent en charge une sorte d'extension des paramètres qui peut vous aider. En bash, vous pouvez utiliser
Dans
dash
, les décalages ne sont pas pris en charge, mais vous pouvez utiliser des modèles de début et de fin:la source
Tout d'abord, n'utilisez pas de
for
boucle pour les noms de fichiers.Ensuite, quelque chose comme ça devrait aider.
la source
for
avec des noms de fichiers?printf
pour être plus sûr. ... etread -r
.for
boucle de l'OP était correcte sauf peut-être pour les disparus--
. Je peux voir au moins 10 bugs dans vos 4 lignes de code! dont beaucoup de mauvaises pratiques bien connues comme supposer que les noms de fichiers sont sur une seule ligne, utiliser l'écho, les guillemets manquants