Je veux transformer /foo/bar/..
a /foo
Existe-t-il une commande bash qui permet de faire cela ?
Edit : dans mon cas pratique, le répertoire existe bien.
Je veux transformer /foo/bar/..
a /foo
Existe-t-il une commande bash qui permet de faire cela ?
Edit : dans mon cas pratique, le répertoire existe bien.
Si vous voulez couper une partie d'un nom de fichier à partir du chemin, "dirname" et "basename" sont vos amis, et "realpath" est pratique aussi.
dirname /foo/bar/baz
# /foo/bar
basename /foo/bar/baz
# baz
dirname $( dirname /foo/bar/baz )
# /foo
realpath ../foo
# ../foo: No such file or directory
realpath /tmp/../tmp/../tmp
# /tmp
realpath
alternatives
Si realpath
n'est pas supporté par votre shell, vous pouvez essayer
readlink -f /path/here/..
Aussi
readlink -m /path/there/../../
Fonctionne de la même manière que
realpath -s /path/here/../../
en ce sens que le chemin n'a pas besoin d'exister pour être normalisé.
Pour ceux d'entre vous qui ont besoin d'une solution OS X, consultez la réponse d'Adam Liss ci-dessous.
stackoverflow.com/a/17744637/999943 Il s'agit d'une réponse fortement liée ! Je suis tombé sur ces deux messages d'AQ en une seule journée, et je voulais les relier entre eux.
Realpath semble avoir été ajouté à coreutils en 2012. Voir l'historique du fichier à github.com/coreutils/coreutils/commits/master/src/realpath.c .
Cela normalisera mais ne résoudra pas les liens mous. Il peut s'agir d'un bogue ou d'une fonctionnalité :-)
Il y a aussi un problème si $CDPATH est défini ; parce que le "cd foo" basculera dans n'importe quel répertoire "foo" qui est un sous-répertoire de $CDPATH, et pas seulement un "foo" qui est dans le répertoire courant. Je pense que vous devez faire quelque chose comme : CDPATH="" cd "${dirToNormalize}" && pwd -P.
Je ne connaissais pas le CDPATH - ça a l'air très bien ! Je peux cependant imaginer des situations où la possibilité de référencer le répertoire dans CDPATH est exactement ce que vous voulez. L'utilisation d'un caractère de tête ./
le réparer aussi ?
Essayez realpath
. Vous trouverez ci-dessous l'intégralité de la source, qui fait l'objet d'un don au domaine public.
// realpath.c: display the absolute path to a file or directory.
// Adam Liss, August, 2007
// This program is provided "as-is" to the public domain, without express or
// implied warranty, for any non-profit use, provided this notice is maintained.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <limits.h>
static char *s_pMyName;
void usage(void);
int main(int argc, char *argv[])
{
char
sPath[PATH_MAX];
s_pMyName = strdup(basename(argv[0]));
if (argc < 2)
usage();
printf("%s\n", realpath(argv[1], sPath));
return 0;
}
void usage(void)
{
fprintf(stderr, "usage: %s PATH\n", s_pMyName);
exit(1);
}
Est-ce que cela fait partie de l'installation standard de bash ? J'obtiens "command not found" sur notre système (bash 3.00.15(1) sur RHEL).
gnu.org/software/coreutils pour readlink, mais realpath vient de ce paquet : paquets.debian.org/unstable/utils/realpath
Jay, Kent, merci d'avoir vérifié Realpath. Je n'étais pas au courant qu'un utilitaire était disponible chez debian ; celui ci-dessus est bien plus simple et a été développé indépendamment. La version Debian fournit des fonctionnalités supplémentaires.
Une solution portable et fiable consiste à utiliser python, qui est préinstallé à peu près partout (y compris sur Darwin). Vous avez deux options :
abspath
renvoie un chemin absolu mais ne résout pas les liens symboliques :
python -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/file
realpath
renvoie un chemin absolu et, ce faisant, résout les liens symboliques, générant un chemin canonique :
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/file
Dans chaque cas, path/to/file
peut être un chemin relatif ou absolu.
Merci, c'est la seule qui a fonctionné. readlink ou realpath ne sont pas disponibles sous OS X. Python devrait l'être sur la plupart des plateformes.
Juste pour clarifier, readlink
est disponible sous OS X, mais pas avec la fonction -f
option. Solutions de contournement portables discutées aquí .
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
4 votes
Est-ce important si
/foo/bar
ou même/foo
existent réellement, ou êtes-vous seulement intéressé par l'aspect de la manipulation des chaînes de caractères selon les règles des noms de chemin ?5 votes
@twalberg ... c'est un peu artificiel...
2 votes
@CamiloMartin Pas du tout artificiel - il fait exactement ce que la question demande - il transforme.
/foo/bar/..
a/foo
et en utilisant unbash
commande. S'il existe d'autres exigences qui ne sont pas mentionnées, alors peut-être devraient-elles l'être...16 votes
@twalberg Tu as fait trop de TDD -_-'