كيف يمكنني إنشاء دلائل خلال نسخة في باش / ZSH / KSH؟
-
13-09-2019 - |
سؤال
أحصل على الرسائل التالية في كثير من الأحيان، على سبيل المثال عند التعامل مع ملفات DEV إلى فرع رئيسي
cp: /Users/Masi/gitHub/shells/zsh/dvorak: No such file or directory
cp: /Users/Masi/gitHub/shells/zsh/dvorak2: No such file or directory
أود أن أسأل عن إنشاء مجلدات معينة بحيث سيتم تشغيل الأمر الأولي إذا أجب بنعم على السؤال (الأسئلة).
محاولتي في كود الزائفة عندما أحاول نسخ ملف إلى دليل لا يوجد
if no such a directory exists, then asks users about to create it:
if yes, then mkdir directory AND run the initial command again
else do noting
مشاكل
- لتغيير رسالة التحذير: ما هو الملف الذي يتحكم في "أي ملف أو دليل مثل هذا الملف"؟
- لتخفيف المسار في الأمر الأولي ومسار MKIDR دون الملف: كيف سيشحن المسار في الأمر الأولي؟
- إلى كشط من النهاية مع لغتك المختارة مثل AWK: كيف يمكنك إزالة آخر تطابق في المسار عند / هل فاصل الحقل؟ لست متأكدا من كيفية كشك الحروف بدءا من النهاية مع AWK.
المحلول
فيما يلي وظيفة كتبتها التي ستعمل في ZSH أو Bash أو Ksh.
ملحوظة: لقد تم تمكين تصحيح الأخطاء (صدى الأوامر التي سترشحها بدلا من تنفيذها). إذا قمت بالتعليق على هذا الخط، فسوف يقوم بالفعل بتشغيلها.
الحذر: لم يتم اختباره جيدا.
لاستخدامها، ضع هذا البرنامج النصي في ملف يسمى cpmd
في /usr/local/bin
(أو في أي مكان آخر في طريقك). لتنشيطها، من نوع موجه Shell الأمر التالي (أو إضافته إلى البرنامج النصي لبدء التشغيل - ل BASH سيكون ~/.bashrc
):
source cpmd
ثم يمكنك نسخ ملف باستخدام أمر مثل هذا:
cpmd carparts /home/dave/Documents/nonexistent/newdir/
لا يوجد دليل "غير موجود" أو "NEMEDIR" بعد. يتم إنشاء كل من الدلائل ثم يتم نسخ الملف المسمى "Carparts" إلى "Newdir".
إذا لم تقم بتضمين مائل ("/") في النهاية، يتم التعامل مع الجزء الأخير كاسم ملف وأي دلائل غير موجودة قبل إنشاء ذلك:
cpmd supplies /home/dave/Documents/anothernew/consumables
يتم إنشاء الدليل "AnotherNew" ثم يتم نسخ "الإمدادات" مع اسم الملف الجديد "المواد الاستهلاكية".
إذا كانت جميع الأدلة الموجودة في الوجهة موجودة بالفعل، cpmd
أعمال مثل العادية cp
أمر.
function cpmd {
# copies files and makes intermediate dest. directories if they don't exist
# for bash, ksh or zsh
# by Dennis Williamson - 2009-06-14
# http://stackoverflow.com/questions/993266/unable-to-make-nosuchdirectory-message-useful-in-zsh
# WARNING: no validation is performed on $1 and $2
# all cp commands below are hardcoded with -i (interactive) to prevent overwriting
if [[ -n $KSH_VERSION ]]
then
alias local=typeset
local func="$0"
local lastchar="${2: -1}"
readcmd () { read "$2?$1"; }
elif [[ -n $ZSH_VERSION ]]
then
local func="$0"
# the following two lines are split up instead of doing "${2[-1]}"
# to keep ksh from complaining when the function is loaded
local dest="$2"
local lastchar="${dest[-1]}"
readcmd () { read "$2?$1"; }
elif [[ -n $BASH_VERSION ]]
then
local func="$FUNCNAME"
local lastchar="${2:(-1)}"
readcmd () { read -p "$1" $2; }
else
echo "cpmd has only been tested in bash, ksh and zsh." >&2
return 1
fi
local DEBUG='echo' # COMMENT THIS OUT to make this function actually work
if [[ ${#@} != 2 ]]
then
echo "$func: invalid number of parameters
Usage:
$func source destination
where 'destination' can include nonexistent directories (which will
be created). You must end 'destination' with a / in order for it to
specify only directories. Without the final slash, the 'source' will
be copied with a new name (the last portion of 'destination'). If you
are copying multiple files and 'destination' is not a directory, the
copy will fail." >&2
return 1
fi
local dir=$(dirname "$2")
local response
local nl=$'\n'
# destination ($2) is presumed to be in one of the following formats:
# .../existdir test 1 (-d "$2")
# .../existdir/existfile test 2 (-f "$2")
# .../existdir/newfile test 3 (-d "$dir" && $lastchar != '/')
# .../existdir/newdir/ (else)
# .../newdir/newdir/ (else)
# .../newdir/newfile (else)
if [[ -d "$2" || -f "$2" || (-d "$dir" && $lastchar != '/') ]]
then
$DEBUG cp -i "$1" "$2"
else
if [[ $lastchar == '/' ]]
then
dir="$2"
fi
local prompt="$func: The destination directory...${nl} ${dir}${nl}...does not exist. Create? (y/n): "
while [[ -z $response ]]
do
readcmd "$prompt" response
case $response in
y|Y) response="Y" ;;
n|N) ;;
*) response=
prompt="$func: Invalid response.${nl} Create destination directory? (y/n): ";;
esac
done
if [[ $response == "Y" ]]
then
$DEBUG mkdir -p "$dir" && $DEBUG cp -i "$1" "$2"
else
echo "$func: Cancelled." >&2
fi
fi
}
نصائح أخرى
رسالة الخطأ هذه تأتي من cp
القيادة، وليس zsh. إذا كنت ترغب في تحسين الإخراج، فسيتعين عليك كتابة المنطق في اقتطاع المسار وتفحصه جنبا إلى جنب مع التحقق لمعرفة ما إذا كان موجودا أم لا.
هناك أوامر للمساعدة في ذلك، إلقاء نظرة على اسم البسري (1) و DirName (1).