Я пытаюсь написать сценарий bash. В этом скрипте я хочу, чтобы пользователь ввел путь к каталогу. Затем я хочу добавить несколько строк в конец этой строки и построить путь к некоторым подкаталогам. Например, предположим, что пользователь вводит такую строку:
/home/user1/MyFolder
Теперь я хочу создать в этом каталоге 2 подкаталога и скопировать туда несколько файлов.
/home/user1/MyFolder/subFold1
/home/user1/MyFolder/subFold2
Как я могу это сделать?
Ответы:
Стандарт POSIX требует, чтобы несколько файлов
/
рассматривались как одно/
в имени файла. Таким образом//dir///subdir////file
то же самое, что и/dir/subdir/file
.Таким образом, объединение двух строк для построения полного пути выполняется просто:
full_path="$part1/$part2"
источник
"" + "/" + "Documents"
дает"/Documents"
../
в начало. Но, возможно, пользователь хочет объединить абсолютные пути. В противном случае они могли бы просто добавить./
переднюю часть, чтобы путь был относительным. Также обратите внимание, что"$path1/./$path2"
это то же самое, что и"$path1/$path2"
.#!/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
И если вы хотите использовать строку чтения, чтобы получить завершение и все такое, добавьте
-e
к вызовуread
:read -e -p "Enter a directory: " BASEPATH
источник
Разве простое соединение части вашего пути не приведет к желаемому результату?
$ base="/home/user1/MyFolder/" $ subdir="subFold1" $ new_path=$base$subdir $ echo $new_path /home/user1/MyFolder/subFold1
Затем вы можете создать папки / каталоги по мере необходимости.
Одно из соглашений заключается в том, чтобы заканчивать пути к каталогам
/
(например/home/
), потому что пути, начинающиеся с /, можно спутать с корневым каталогом. Если в пути используется двойная косая черта (//
), это тоже правильно. Но, если для какой-либо переменной не используется косая черта, это будет неправильно (например/home/user1/MyFoldersubFold1
).источник
/home/user1/MyFolder/subFold1
поэтому вам понадобится встроенная функцияnew_path=$base/$subdir
. Но что тогда делать, если указанный путь включает завершающий '/'?newpath=$base/$subdir/
вы можете поиграть с этим непосредственно в командной строкеСледующий скрипт связывает несколько (относительных / абсолютных) путей (BASEPATH) с относительным путем (SUBDIR):
shopt -s extglob SUBDIR="subdir" for BASEPATH in '' / base base/ base// /base /base/ /base//; do echo "BASEPATH = \"$BASEPATH\" --> ${BASEPATH%%+(/)}${BASEPATH:+/}$SUBDIR" done
Результатом является:
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
Это
shopt -s extglob
необходимо только для того, чтобы BASEPATH заканчивался несколькими косыми чертами (что, вероятно, бессмысленно). Без расширенного подстановки вы можете просто использовать:echo ${BASEPATH%%/}${BASEPATH:+/}$SUBDIR
что приведет к менее аккуратному, но все еще работающему:
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
источник
Я работал со своим сценарием оболочки, который должен делать некоторые пути, соединяющие вещи, как вы.
Дело в том, что оба пути похожи на
действительны.
Если я хочу добавить файл по этому пути, например
в оболочке не было собственного метода (например, os.path.join () в python) для обработки такой ситуации.
Но я нашел уловку
Например, базовый путь был сохранен в переменной оболочки
и последнее имя файла, к которому вы хотите присоединиться, было
Затем вы можете назначить свой новый путь следующим образом
NEW_PATH=$(realpath ${BASE})/FILE
и тогда вы получите
$ echo $NEW_PATH /path/to/your/home/mydir/myfile
причина довольно проста, команда "realpath" всегда будет обрезать завершающую косую черту для вас, если необходимо
источник
#!/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 "$@"
источник
Это должно работать для пустого каталога (вам может потребоваться проверить, начинается ли вторая строка, с
/
которой следует рассматривать как абсолютный путь?):#!/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
Выход:
Ссылка: Расширение параметров оболочки
источник