Affecter uniquement une partie d'une chaîne à une variable dans bash

11

Je reçois de l'utilisateur un certain chemin de fichier absolu, et je veux créer une variable qui sera une chaîne qui n'inclura pas seulement les deux premiers composants du chemin de fichier, mais sans l'imprimer ou quoi que ce soit.

Par exemple, le chemin absolu pourrait être:

/home/myusername/folder1/folder2/folder3

Et il est enregistré dans "target_path", et je veux que "mydir" soit seulement:

/folder1/folder2/folder3

J'ai essayé d'utiliser la commande cut de différentes manières mais sans succès.

La vie de pi
la source
Est- /home/usernamece le $HOMErépertoire réel de l'utilisateur appelant? si c'est le cas, vous pouvez le supprimer simplement en utilisant mydir="${target_path#$HOME}"je pense
steeldriver

Réponses:

15

Utilisation de la manipulation de chaînes de bash :

$ a=/home/myusername/folder1/folder2/folder3
$ echo "${a#/*/*/}"
folder1/folder2/folder3

Ainsi, la chaîne que vous souhaitez serait (en ajoutant à nouveau la barre oblique):

b="/${a#/*/*/}"

Pour une variable a, ${a#foo}supprimera la chaîne la plus courte correspondant fooau début de a. Ainsi, nous supprimons la chaîne la plus courte contenant trois /(y compris la barre oblique principale dans le chemin), pour supprimer les deux premiers composants du chemin absolu.

muru
la source
Le chemin peut être de 30 dossiers, et je veux seulement inclure les 28 derniers. Est-ce que cela fonctionnera toujours?
Vie de pi
@Lifeofpi pourquoi pas?
muru
9

Voici un exemple d'utilisation cut

echo "/home/myusername/folder1/folder2/folder3" | cut -d '/' -f4- 

folder1/folder2/folder3

Si vous avez besoin de l'interligne, /vous pouvez l'ajouter | sed 's/^/\//'à la fin de votre ligne.

Vous en avez besoin, -f4-car il -d '/'indique cutd'utiliser /comme délimiteur entre les champs. Le premier champ vient donc avant le premier délimiteur, dans ce cas le premier champ est vide. Il en folder1va de même pour le 4ème champ et -f4-indique à cut d'utiliser tous les champs à partir du 4ème.

guntbert
la source
7

Vous pouvez utiliser l'expansion des paramètres bash comme ceci:

target_path=/home/username/folder1/folder2/folder3
myvar="/${target_path#/*/*/}"

Après ça:

echo $myvar

donne:

/folder1/folder2/folder3

Cela fonctionne en supprimant la première correspondance du modèle /*/*/de votre variable target_path, en utilisant la ${target_path#pattern}syntaxe d'expansion des paramètres du shell. Malheureusement, cela supprime le premier /caractère, c'est pourquoi ce caractère doit être explicitement inclus lors de la définition de la variable myvar.

Avertissement: vous devez vérifier que votre variable target_path contient certains caractères et qu'elle est plus longue que deux segments de chemin avant d'utiliser cette méthode. Par exemple si target_path=/home/username/, alors myvar=/. Cela pourrait être dangereux pour votre système si vous exécutez quelque chose comme rm -rf "$myvar"*. N'essaye pas ça!

Arronical
la source
Le chemin peut être de 30 dossiers, et je veux seulement inclure les 28 derniers. Est-ce que cela fonctionnera toujours?
Vie de pi
Certainement, cela ne fera que couper les deux premiers, quelle que soit la longueur du chemin.
Arronical