Bash - Manipulation de chaîne continue


11
#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

Existe-t-il de toute façon de coller ces deux lignes ensemble dans une doublure?

Réponses:


12

FILE=$(basename "${1/%.jpeg/.jpg}") travaillé pour moi.

tester:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

contenu du script:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"

Étant donné que les deux lignes sont un peu interchangeables, cette solution est jusqu'à présent la plus soignée ... Si les lignes ne sont pas interchangeables, sedelles seront définitivement nécessaires, je suppose.
gsklee

11

Vous ne pouvez pas imbriquer d'extensions dans bash (ni dans ksh, ash et autres coquilles en dehors de zsh). Il ne s'agit que d'une limitation esthétique, car, comme vous l'illustrez, vous pouvez affecter une expression intermédiaire à une variable temporaire. C'est un peu ennuyeux pour les monolignes, mais dans les scripts, c'est sans doute meilleur pour la lisibilité.

Vous pouvez éviter d'utiliser l'utilitaire externe basenameet utiliser une construction de manipulation de chaîne à la place:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

Ici, il arrive que vous puissiez réécrire votre script pour mettre la substitution de commandes à l'extérieur . Ce n'est pas un phénomène général, et vous ne gagnez rien d'autre qu'un certain sentiment de doublure.

Zsh, pour le meilleur ou pour le pire, vous permet d'imbriquer des extensions:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

Ou vous pouvez utiliser la construction intégrée de zsh au lieu de basename:

FILE=${${1:t}/%.jpeg/.jpg}

4

J'irais pour:

FILE=$(basename $1 .jpeg).jpg

Le deuxième paramètre de basename est un suffixe à supprimer du nom de fichier (voir man basename)


3

Vous pouvez utiliser une seule sedcommande comme dans l'exemple suivant:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")

2

L'intégration sed, cela devrait faire l'affaire:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(Cela ne répond pas exactement à votre question parce que je ne peux pas; je ne sais pas si c'est possible.)


1

Les ${}constructions Bash fonctionnent avec des noms de variables , il n'y a donc aucun moyen d'incorporer une commande directement. L'approche de @ sr_ est une alternative si cela ne vous dérange pas le fork supplémentaire.


1

La ligne

FILE=$(basename "${1/%.jpeg/.jpg}")

peut être raccourci et rendu plus portable avec

FILE=$(basename "${1%.jpeg}.jpg")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.