web-dev-qa-db-fra.com

Comment concaténer deux chaînes pour construire un chemin complet

J'essaie d'écrire un script bash. Dans ce script, je veux que l'utilisateur entre le chemin d'un répertoire. Ensuite, je souhaite ajouter des chaînes à la fin de cette chaîne et créer un chemin vers certains sous-répertoires . Par exemple, supposons que l'utilisateur entre une chaîne comme celle-ci:

/home/user1/MyFolder

Maintenant, je veux créer 2 sous-répertoires dans ce répertoire et y copier des fichiers.

/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2

Comment puis-je faire ceci?

60
Hakim

La norme POSIX exige que plusieurs / soient traités comme un seul / dans un nom de fichier. Ainsi, //dir///subdir////file est identique à /dir/subdir/file.

En tant que tel, concaténer deux chaînes pour créer un chemin complet est simple:

full_path="$part1/$part2"
91
Dunes
#!/bin/bash

read -p "Enter a directory: " BASEPATH

SUBFOLD1=${BASEPATH%%/}/subFold1
SUBFOLD2=${BASEPATH%%/}/subFold2

echo "I will create $SUBFOLD1 and $SUBFOLD2"

# mkdir -p $SUBFOLD1
# mkdir -p $SUBFOLD2

Et si vous voulez utiliser readline afin d’être complet et tout le reste, ajoutez un -e à l’appel de read:

read -e -p "Enter a directory: " BASEPATH
32
Sean Bright

Ne concaténez-vous pas simplement la partie de votre chemin accomplissant ce que vous voulez?

$ base="/home/user1/MyFolder"
$ subdir="subFold1"
$ new_path=$base$subdir
$ echo $new_path
/home/user1/MyFoldersubFold1

vous pouvez ensuite créer les dossiers/répertoires selon vos besoins.

11
Levon

Le script suivant identifie plusieurs chemins (relatifs/absolus) (BASEPATH) avec un chemin relatif (SUBDIR):

shopt -s extglob
SUBDIR="subdir"
for BASEPATH in '' / base base/ base// /base /base/ /base//; do
  echo "BASEPATH = \"$BASEPATH\" --> ${BASEPATH%%+(/)}${BASEPATH:+/}$SUBDIR"
done

Le résultat est:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base/subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base/subdir

Le shopt -s extglob est uniquement nécessaire pour permettre à BASEPATH de se terminer sur plusieurs barres obliques (ce qui est probablement absurde). Sans globing étendu, vous pouvez simplement utiliser:

echo ${BASEPATH%%/}${BASEPATH:+/}$SUBDIR

ce qui rendrait les moins soignés mais fonctionnant toujours:

BASEPATH = "" --> subdir
BASEPATH = "/" --> /subdir
BASEPATH = "base" --> base/subdir
BASEPATH = "base/" --> base/subdir
BASEPATH = "base//" --> base//subdir
BASEPATH = "/base" --> /base/subdir
BASEPATH = "/base/" --> /base/subdir
BASEPATH = "/base//" --> /base//subdir
5
Carlo Wood
#!/usr/bin/env bash

mvFiles() {
    local -a files=( file1 file2 ... ) \
             subDirs=( subDir1 subDir2 ) \
             subDirs=( "${subDirs[@]/#/$baseDir/}" )

    mkdir -p "${subDirs[@]}" || return 1

    local x
    for x in "${subDirs[@]}"; do
        cp "${files[@]}" "$x"
    done
}



main() {
    local baseDir
    [[ -t 1 ]] && echo 'Enter a path:'
    read -re baseDir
    mvFiles "$baseDir"
}

main "$@"
0
ormaaj

Je travaillais avec mon script Shell qui doit créer un chemin pour rejoindre des choses comme vous le faites.

La chose est, les deux chemin comme

/data/foo/bar

/data/foo/bar/ 

sont valides.

Si je veux ajouter un fichier à ce chemin comme

/data/foo/bar/myfile

shell ne disposait d'aucune méthode native (comme os.path.join () en python) pour gérer cette situation.

Mais j'ai trouvé un truc

Par exemple, le chemin de base était stocké dans une variable Shell

BASE=~/mydir

et le dernier nom de fichier que vous voulez rejoindre était

FILE=myfile

Ensuite, vous pouvez assigner votre nouveau chemin comme ceci

NEW_PATH=$(realpath ${BASE})/FILE

et alors vous aurez

$ echo $NEW_PATH

/path/to/your/home/mydir/myfile

la raison en est simple, la commande "realpath" réduira toujours la barre oblique pour vous si nécessaire

0
余晓晨

Cela devrait fonctionner pour un répertoire vide (vous devrez peut-être vérifier si la deuxième chaîne commence par / qui devrait être considéré comme un chemin absolu?):

#!/bin/bash

join_path() {
    echo "${1:+$1/}$2" | sed 's#//#/#g'
}

join_path "" a.bin
join_path "/data" a.bin
join_path "/data/" a.bin

Sortie:

a.bin
/data/a.bin
/data/a.bin

Référence: Shell Parameter Expansion

0
tsl0922