8
votes

Comment puis-je chaîner des modificateurs de nom de fichier dans une coquille bash?

Je comprends les modificateurs ## %%%, mais je ne peux pas comprendre si c'est possible de les chaîner ensemble comme vous le pouvez dans TCSH.

Exemple dans tcsh xxx

à bash, j'aimerais savoir comment faire quelque chose comme: xxx

en une ligne.

Mon objectif est de Soyez capable de manipuler des noms de fichiers de différentes manières, au besoin sur la ligne de commande. Je n'essaie pas d'écrire un script pour un cas spécifique. Donc, s'il y a un moyen de chaîner ces modificateurs ou peut-être qu'il y a une autre façon, alors j'aimerais savoir. Merci


0 commentaires

3 Réponses :


7
votes

en bash, vous pouvez nier les extensions de paramètre em> mais seulement efficacement dans la partie mot em> dans $ {paramètre # word} code>.

Par exemple: P>

$ var="/foo/bar/myfile.0076.jpg"; set -- ${var//[.\/]/ }; echo $4
0076


5 commentaires

Je vois. Ainsi, lorsque la partie mot est toujours supprimée du début ou de la fin du paramètre, la modification de la partie de mot ne peut modifier que la quantité de suppression de la quantité. Il ne peut jamais se dépouiller un peu du début et un peu de la fin d'une ligne.


Droite, vous êtes essentiellement enfermé dans l'expansion de paramètres de gauche (# dans mon exemple). Si BASH vous a permis d'obtenir la longueur d'une variable expansée par paramètre en une fois, comme $ {# var # foo.bar} (ne fonctionne pas) alors vous pouvez potentiellement faire ce que vous voulez via le Extransion de paramètre offset $ {paramètre: décalage: longueur}


Oui, je vois qu'il y a beaucoup de modificateurs qui le rendent possible avec un peu d'effort, mais cela n'arrive pas tout à fait. Peut-être que je vais essayer de brosser sur SED et d'utiliser des tuyaux. Merci de votre aide.


@Julian définir ou même lire serait plus rapide que l'appelant sed car c'est un binaire externe et causerait bash à la recherche d'un nouveau processus.


merci@siegex. J'ai trouvé une solution pour obtenir des modificateurs chaînées de style TCSH travaillant. Et puisque voir cela, je l'ai édité, TOI Évitez les SED. Je posterai comme une réponse.



3
votes

Une façon dont vous pouvez faire ce que vous essayez de réaliser est d'utiliser les regextes de Bash (version 3.2 et ultérieure).

bn ()
{
    [[ $1 == / ]] && echo / || echo "${1##*/}"
}

dn ()
{
    [[ -z ${1%/*} ]] && echo / || {
        [[ $1 == .. ]] && echo . || echo "${1%/*}"
    }
}


1 commentaires

Merci pour ceux-ci. Il semble que Bash est très puissant comparé à TCSH, mais pour modifier les noms de fichiers, ce n'est pas le type de syntaxe que je pourrais utiliser de manière ad hoc sur la ligne de commande tous les jours. Heureusement, vous pouvez conclure des expressions utiles telles que celles que vous avez suggérées, dans les fonctions et les mettre en BACHRC.



1
votes

J'ai trouvé une solution qui se rapproche assez de la simplicité des modificateurs de nom de fichier TCSH. J'ai écrit 4 fonctions et mettez-les dans .CASHRC.

#If there are no args, then assume input comes from a pipe.

function e(){
    if [ $# -ne 0 ]; then
        echo ${1##*.}  
    else
        while read data; do
            echo  ${data##*.}   ; 
        done
    fi
}

function E(){
    if [ $# -ne 0 ]; then
        echo ${1%.*} 
    else
        while read data; do
            echo ${data%.*}
        done
    fi
}

function t(){
    if [ $# -ne 0 ]; then
        echo ${1##*/}  
    else
        while read data; do
            echo  ${data##*/}   ; 
        done
    fi
}

function T(){
    if [ $# -ne 0 ]; then
        echo ${1%/*} 
    else
        while read data; do
            echo ${data%/*}
        done
    fi
}


3 commentaires

+1 - Notez que votre t () est similaire à BasEname et votre t () est similaire à dirname . Je posterai ma version de ceux comme édités à ma réponse. Ils gèrent des cas de bord de la manière dont les utilitaires réels font.


Je pense que votre manipulation robuste de cas de bord combinée à la capacité de lire l'entrée d'un tuyau (ma réponse), ferait les outils de manipulation du nom de fichier idéal à Bash. Bien mieux que ce qui est disponible par défaut.


FYI, en utilisant le mot-clé rend votre code moins portable que ce serait sans elle - juste t () { with No fonction précédent est (L'ouverture de) une déclaration de fonction compatible POSIX et fonctionnera même avec des cendres ou des tirettes.