ডিরেক্টরি তৈরি করার কোনও উপায় নেই যদি এমভি ডিরেক্টরিটি না উপস্থিত থাকে তবে তা সরানো হবে?


275

সুতরাং, আমি যদি আমার হোম ডিরেক্টরিতে থাকি এবং আমি foo.c- কে bar / বার / বাজ / foo.c এ স্থানান্তর করতে চাই তবে সেই ডিরেক্টরিগুলি বিদ্যমান নেই, সেই ডিরেক্টরিগুলি স্বয়ংক্রিয়ভাবে তৈরি করার কোনও উপায় আছে, যাতে আপনি কেবল টাইপ করতে হবে

mv foo.c ~/bar/baz/ 

এবং সবকিছু কাজ করবে? দেখে মনে হচ্ছে আপনি একটি সাধারণ বাশ স্ক্রিপ্টে উপন্যাস এমভি করতে পারেন যা এই ডিরেক্টরিগুলি বিদ্যমান কিনা তা পরীক্ষা করে দেখতে পারে এবং যদি এমকেডির এবং তারপরে এমভি কল না করে তবে আমি ভেবেছিলাম যে আমি আরও ভাল ধারণা পেয়েছি কিনা তা যাচাই করে নেব।


সম্পর্কিত: stackoverflow.com/questions/1529946/...
kvantour

উত্তর:


294

এই ওয়ান-লাইনার সম্পর্কে (ব্যাশে):

mkdir --parents ./some/path/; mv yourfile.txt $_

এটি ভেঙে:

mkdir --parents ./some/path

ডিরেক্টরি তৈরি করে (সমস্ত মধ্যবর্তী ডিরেক্টরি সহ) যার পরে:

mv yourfile.txt $_

ফাইলটিকে সেই ডিরেক্টরিতে স্থানান্তরিত করে ($ _ পূর্ববর্তী শেল কমান্ডে প্রেরিত সর্বশেষ আর্গুমেন্টে প্রসারিত হয়, যেমন: নতুন নির্মিত ডিরেক্টরি)।

অন্যান্য শাঁসে এটি কতদূর কাজ করবে তা আমি নিশ্চিত নই তবে এটি আপনাকে কী সন্ধান করবে সে সম্পর্কে কিছু ধারণা দিতে পারে।

এই কৌশলটি ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হল:

$ > ls
$ > touch yourfile.txt
$ > ls
yourfile.txt
$ > mkdir --parents ./some/path/; mv yourfile.txt $_
$ > ls -F
some/
$ > ls some/path/
yourfile.txt


1
অনর্থক কেন ./সব জায়গায় আবেশ ? আরএটিএইচগুলি .ডিরেক্টরি ছাড়া PATH তে কমান্ড নয় ...
জেনস


8
অদ্ভুতভাবে, --parentsম্যাকোস 10.13.2 এ উপলব্ধ নয়। আপনার ব্যবহার করা দরকার -p
জোশুয়া পিন্টার

1
কোনও ফাইলকে সরানো হলে কাজ করে না যেমন ./some/path/foo। এক্ষেত্রে কমান্ডটি হওয়া উচিত:mkdir -p ./some/path/foo; mv yourfile.txt $_:h
এইচবিলি

63
mkdir -p `dirname /destination/moved_file_name.txt`  
mv /full/path/the/file.txt  /destination/moved_file_name.txt

2
আমি একমাত্র এই কোডটি উপলব্ধি করতে পারছি না? আপনি বিদ্যমান ফাইলটিতে পুনরাবৃত্তভাবে নিখুঁত পথ তৈরি করেন (যার অর্থ এই পথটি ইতিমধ্যে বিদ্যমান) এবং তারপরে ফাইলটি একটি লোকেশনে স্থানান্তরিত করুন (যা আপনার উদাহরণে উপস্থিত নেই)।
vdegenne

1
@ user544262772 GNU কোর্টিলস ' dirnameএর যুক্তি উপস্থিত থাকার প্রয়োজন নেই, এটি খাঁটি স্ট্রিং ম্যানিপুলেশন। অন্যান্য বিতরণের জন্য কথা বলতে পারে না। এই কোডটি আফিকেট দিয়ে কোনও ভুল নেই।
ট্রয়হার্টস

এটি এই উত্তরটি যা খুব সহজেই স্বয়ংক্রিয় হয়, আমি মনে করি। for f in *.txt; do mkdir -p `dirname /destination/${f//regex/repl}`; mv "$f" "/destination/${f//regex/repl}; done
কাইল

23

Mv বা mv.sh নামের স্ক্রিপ্ট হিসাবে সংরক্ষণ করুন

#!/bin/bash
# mv.sh
dir="$2"
tmp="$2"; tmp="${tmp: -1}"
[ "$tmp" != "/" ] && dir="$(dirname "$2")"
[ -a "$dir" ] ||
mkdir -p "$dir" &&
mv "$@"

অথবা আপনার ~ / .bashrc ফাইলটির শেষে একটি ফাংশন হিসাবে রাখুন যা প্রতিটি নতুন টার্মিনালে ডিফল্ট এমভি প্রতিস্থাপন করে। কোনও ফাংশন ব্যবহার করে প্রতিবার স্ক্রিপ্ট ফাইলটি পড়ার পরিবর্তে বাশ এটিকে মেমরি রাখতে দেয়।

function mv ()
{
    dir="$2"
    tmp="$2"; tmp="${tmp: -1}"
    [ "$tmp" != "/" ] && dir="$(dirname "$2")"
    [ -a "$dir" ] ||
    mkdir -p "$dir" &&
    mv "$@"
}

এগুলি ক্রিস লুটজ জমা দেওয়ার উপর ভিত্তি করে।


3
এই প্রশ্নের উত্তর দেয় সবচেয়ে সঠিকভাবে আইএমএইচও। ব্যবহারকারী একটি বর্ধিত mvকমান্ড চান like স্ক্রিপ্টিংয়ের জন্য বিশেষত কার্যকর, অর্থাত্ আপনি চেকগুলি চালাতে চান না এবং mkdir -pযে কোনও সময় আপনার প্রয়োজন পড়ার প্রয়োজন হয় mv। তবে যেহেতু আমি ডিফল্ট ত্রুটি আচরণটি চাইব mv, তাই আমি ফাংশনটির নাম পরিবর্তন করে রেখেছি mvp- যাতে আমি জানি যে আমি কখন ডিরেক্টরি তৈরি করতে পারি।
ব্রায়ান ডানকান

সেরা সমাধানের আইডিয়াটির মতো দেখে মনে হচ্ছে, বুটিমপ্লিমেন্টেশন অনেকগুলি ক্র্যাশ।
উলিসেস লেয়েরা

2
অ্যালগোরিদমকে আরও শক্তিশালী করার জন্য আমি ইউলাইজ লাইরা পরিবর্তন করেছি। এটি এখন ক্রাশ হওয়া উচিত নয়
সেপিরো

কেউ দয়া করে [ ! -a "$dir" ]আমি সঠিক অর্থে সত্য এবং মিথ্যা, উভয়ই সত্য বলে মূল্যায়ন করে পরীক্ষা-নিরীক্ষা করেছি তার অর্থ ব্যাখ্যা করতে পারে .. ??? অন্যের পক্ষে, tmp = "$ mp tmp: -1}" ফাইলের সর্বশেষ অক্ষরটি এটি কোনও পথ (/) নয় তা নিশ্চিত করার জন্য উপস্থিত হয়
বাজ

@ বাজেস এটি করা উচিত "যদি $ দির উপস্থিত না থাকে তবে চালিয়ে যান"। দুর্ভাগ্যক্রমে, আপনি সঠিক, "! -A" ব্যবহার করার সময় একটি বাগ রয়েছে, এবং কেন তা আমি জানি না। আমি কোডটি কিছুটা সম্পাদনা করেছি এবং এখন কাজ করা উচিত।
সেপিরো

13

আপনি ব্যবহার করতে পারেন mkdir:

mkdir -p ~/bar/baz/ && \
mv foo.c ~/bar/baz/

এটি স্বয়ংক্রিয়ভাবে করার জন্য একটি সাধারণ স্ক্রিপ্ট (অরীক্ষিত):

#!/bin/sh

# Grab the last argument (argument number $#)    
eval LAST_ARG=\$$#

# Strip the filename (if it exists) from the destination, getting the directory
DIR_NAME=`echo $2 | sed -e 's_/[^/]*$__'`

# Move to the directory, making the directory if necessary
mkdir -p "$DIR_NAME" || exit
mv "$@"

আমি যখন "ir dirname ~? বার / বাজ /" চালনা করি তখন আমি "/ home / dmckee / bar" পাই যা আপনি এখানে চান না ...
ডিএমকেকে --- প্রাক্তন মডারেটর বিড়ালছানা

@ ডিএমকেহে, আহ, আপনি ঠিক বলেছেন। এটি সমাধান করার জন্য কোনও ধারণা? আপনি যদি ~ / বার / বাজ ইনপুট করেন তবে আপনি (ক) ~ / বার / এ অনুলিপি করতে চান এবং বাজে নাম পরিবর্তন করতে চান, বা (খ) copy / বার / বাজে / অনুলিপি করতে চান। কাজের জন্য আরও ভাল সরঞ্জাম কি?
স্ট্র্যাজার

@ ডিএমকেকে, আমি একটি সমাধান নিয়ে আসতে regexp / sed ব্যবহার করেছি। এটি কি আপনার পছন্দ অনুসারে কাজ করে? =]
স্টারগার

ভাল, $ 2 = ব্যতীত 2 ডলার ব্যতীত শেষ যুক্তিটি নয় la # = 2. আমার একটি প্রোগ্রাম রয়েছে, যা এর শেষ যুক্তি মুদ্রণ করে। আমি এটি সিপি কমান্ডের একটি সংস্করণে ব্যবহার করতাম (যদি বর্তমান যুক্তিটি ডিরেক্টরি না থাকে তবে ডিরেক্টরিটি যুক্ত করতে)। এমনকি আধুনিক শেলগুলি কেবল $ 1 .. $ 9 সমর্থন করে; পার্ল স্ক্রিপ্ট আরও ভাল হতে পারে।
জোনাথন লেফলার

@ লিফলার, সত্য নয় - আমি জানি ব্যাশ 9 টিরও বেশি আর্গুমেন্টকে সমর্থন করে (method {123 using ব্যবহার করা একটি পদ্ধতি) আমি পার্লকে চিনি না, তাই নিজেই উত্তর দিতে নির্দ্বিধায়। =]
স্টারগার

7

মনে হচ্ছে উত্তরটি নেই :)। আমি কেবল এটি করার জন্য কোনও উপাস বা ফানক তৈরি করতে চাই না, প্রায়শই কারণ এটি এক-বন্ধ এবং আমি ইতিমধ্যে mvকমান্ডটি টাইপ করার মাঝখানে আছি তবে আমি এমন একটি কিছু খুঁজে পেয়েছি যা এর জন্য ভালভাবে কাজ করে:

mv *.sh  shell_files/also_with_subdir/ || mkdir -p $_

যদি mvব্যর্থ হয় (ডিয়ারের অস্তিত্ব নেই), এটি ডিরেক্টরিটি তৈরি করবে (যা পূর্ববর্তী কমান্ডের সর্বশেষ যুক্তি, তাই $_এটি রয়েছে)। সুতরাং কেবল এই আদেশটি চালান, তারপরে upএটি পুনরায় চালনা করুন এবং এই mvবারটি সফল হওয়া উচিত।


5

নিম্নলিখিত শেল স্ক্রিপ্ট, সম্ভবত?

#!/bin/sh
if [[ -e $1 ]]
then
  if [[ ! -d $2 ]]
  then
    mkdir --parents $2
  fi
fi
mv $1 $2

এটিই মূল অংশ আপনি আর্গুমেন্টগুলি পরীক্ষা করতে কিছুটা যুক্ত করতে চাইতে পারেন, এবং গন্তব্যটি উপস্থিত থাকলে বা উত্স ডিরেক্টরি উপস্থিত থাকলে বা উপস্থিত না থাকলে আপনি আচরণটি বদলাতে চান (যেমনটি অস্তিত্ব নেই এমন কিছু ওভাররাইট করবেন না) ।


1
আপনার কোড সহ, ডিরেক্টরিটি উপস্থিত না থাকলে পদক্ষেপটি সম্পাদিত হবে না!
স্ট্র্যাজার

1
এবং আপনি এমকেডিরের কাছে "-p" পতাকাটি মিস করেছেন।
ডিএমকেকে --- প্রাক্তন-মডারেটর বিড়ালছানা

যদি কোনও ডিরেক্টরি বিদ্যমান না থাকে তবে আপনি কেন এটি সরাতে চলেছেন যদি এটি তৈরি করেন? (-পি পতাকা ঠিক করা)
ক্রিস লুৎজ

আমি বলতে চাইছি, আপনি যখন স্ক্রিপ্টটি পরিচালনা করেন এবং ডিরেক্টরি $ 2 উপস্থিত থাকে না, এটি তৈরি হয় তবে ফাইলটি অনুলিপি করা হয় না।
স্টারগার

তিনি একটি সাধারণ নির্মাণ দিয়েছেন এবং কীভাবে এটি সম্প্রসারণ করা উচিত সে সম্পর্কে তথ্য যুক্ত করেছিলেন। কেন এটা ভোট ?!
ypnos

5

rsync কমান্ড কেবল তখনই কৌতুক করতে পারে যদি গন্তব্য পথের শেষ ডিরেক্টরিটি উপস্থিত না থাকে, যেমন গন্তব্য পথের জন্য ~/bar/baz/যদি barউপস্থিত থাকে তবে bazতা না থাকে তবে নিম্নলিখিত কমান্ডটি ব্যবহার করা যেতে পারে:

rsync -av --remove-source-files foo.c ~/bar/baz/

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
--remove-source-files   sender removes synchronized files (non-dir)

এই ক্ষেত্রে bazডিরেক্টরিটি উপস্থিত না থাকলে তৈরি করা হবে। কিন্তু যদি উভয় barএবং bazrsync উপস্থিত না থাকার ব্যর্থ হবে:

sending incremental file list
rsync: mkdir "/root/bar/baz" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(657) [Receiver=3.1.2]

সুতরাং মূলত এটির rsync -av --remove-source-filesজন্য একটি উপনাম হিসাবে ব্যবহার করা নিরাপদ হওয়া উচিত mv


4

এটি করার সহজতম উপায় হ'ল:

mkdir [directory name] && mv [filename] $_

ধরা যাক আমি আমার ডাউনলোড ডিরেক্টরিতে অবস্থিত পিডিএফ ফাইলগুলি ডাউনলোড করেছি ( ~/download) এবং আমি তাদের সমস্তটি এমন একটি ডিরেক্টরিতে স্থানান্তর করতে চাই যা বিদ্যমান নেই (আসুন বলিmy_PDF )।

আমি নিম্নলিখিত কমান্ডটি টাইপ করব (আমার বর্তমান কার্যকরী ডিরেক্টরিটি নিশ্চিত করে ~/download):

mkdir my_PDF && mv *.pdf $_

আপনি ঠিক এইভাবে উপ-ডিরেক্টরি তৈরি -pকরতে mkdirচাইলে আপনি বিকল্প যুক্ত করতে পারেন: (অনুমিত আমি নামের একটি উপ-ডিরেক্টরি তৈরি করতে চাই python):

mkdir -p my_PDF/python && mv *.pdf $_

2

সিলিয়ার, কিন্তু কাজের উপায়:

mkdir -p $2
rmdir $2
mv $1 $2

গন্তব্য ফাইলের নাম ভাগ করে নেওয়ার জন্য অস্থায়ী ডিরেক্টরি সহ mkdir -p দিয়ে ডিরেক্টরি তৈরি করুন, তারপরে একটি সরল rmdir দিয়ে ফাইল নাম ডিরেক্টরিটি সরান, তারপরে আপনার ফাইলটিকে নতুন গন্তব্যে নিয়ে যান। আমি মনে করি ডারনাম ব্যবহার করে উত্তর সম্ভবত সবচেয়ে ভাল।


ইয়েপ্প, কিন্ডা মূর্খ। :-) যদি $ 2 ডিরেক্টরি হয় (মূল প্রশ্নের মতো) তবে এটি খারাপভাবে ব্যর্থ হয়, কারণ শেষ ডিরেক্টরিটি মুছে ফেলা হবে, সুতরাং 'এমভি' ব্যর্থ হবে। এবং যদি $ 2 ইতিমধ্যে বিদ্যমান থাকে তবে এটি এটি মোছার চেষ্টা করে।
টায়লা

ধন্যবাদ! এটি হ'ল আমার ঠিক একই কাজটি করা দরকার: এমভি। / ওল্ড। / সুব্বির / নতুন যেখানে সাবডির এখনও বিদ্যমান নেই
মাইক মারে


1

কোড:

if [[ -e $1 && ! -e $2 ]]; then
   mkdir --parents --verbose -- "$(dirname -- "$2")"
fi
mv --verbose -- "$1" "$2"

উদাহরণ:

আর্গুমেন্ট: "d1" "ডি 2 / সাব"

mkdir: created directory 'd2'
renamed 'd1' -> 'd2/sub'

1

এটি প্যারেন্ট ডিরেক্টরি সহ foo.cনতুন ডিরেক্টরিতে চলে যাবে ।bazbar

mv foo.c `mkdir -p ~/bar/baz/ && echo $_`

প্রয়োজনীয় -pবিকল্পটি mkdirমধ্যবর্তী ডিরেক্টরি তৈরি করবে।
ছাড়া-pপাথের সমস্ত ডিরেক্টরি ইতিমধ্যে উপস্থিত থাকতে হবে।

ব্যাকটিকসের ভিতরে থাকা সমস্ত ``কিছুই কার্যকর করা হয় এবং আপনার কমান্ডের অংশ হিসাবে আউটপুট ইন-লাইনে ফিরে আসে।
যেহেতু mkdirকিছুই ফেরত না, কেবল আউটপুট echo $_কমান্ডে যুক্ত হবে।

$_পূর্বে সম্পাদিত কমান্ডের সর্বশেষ যুক্তিটি উল্লেখ করে।
এই ক্ষেত্রে এটি আপনার নতুন ডিরেক্টরিতে ( ~/bar/baz/) প্রবেশ করে returnmkdir কমান্ডে আসবে।


আমি কোনও গন্তব্য না দিয়ে একটি সংরক্ষণাগারটি আনজিপ করেছি এবং demo-app.zipআমার বর্তমান ডিরেক্টরিটি বাদ দিয়ে সমস্ত ফাইল সরিয়ে নিয়ে যেতে চাইলে নতুন ডিরেক্টরিতে ডেকে পাঠাতে চেয়েছিলাম demo-app
নিম্নলিখিত লাইনটি কৌশলটি করে:

mv `ls -A | grep -v demo-app.zip` `mkdir -p demo-app && echo $_`

ls -A(লুকানো ফাইল সহ সব ফাইলের নাম ফেরৎ অন্তর্নিহিত ছাড়া .এবং.. )।

পাইপ প্রতীকটি কমান্ডের |আউটপুট পাইপ করতে ব্যবহৃত হয় ( একটি কমান্ড-লাইন, প্লেইন-পাঠ্য অনুসন্ধানের ইউটিলিটি )। পতাকা নির্দেশ এবং খুঁজে সব ফাইলের নাম ব্যতীত ফিরে যাওয়ার । ফাইলের সেই তালিকাটি মুভ কমান্ডের উত্স আর্গুমেন্ট হিসাবে আমাদের কমান্ড-লাইনে যুক্ত করা হয়েছে । লক্ষ্য যুক্তি হ'ল নতুন ডিরেক্টরিতে পাঠানো যা ব্যবহার করে রেফারেন্স ব্যবহার করে আউটপুট ব্যবহার করে ।lsgrep
-vgrepdemo-app.zip
mvmkdir$_echo


1
এটি বিশদ এবং ব্যাখ্যা - এবং বিশেষত প্রথম পোস্টের জন্য একটি দুর্দান্ত স্তর। ধন্যবাদ!
জেরেমি

আপনাকে ধন্যবাদ, @ জেরেমি কেনে! আমি সাহায্য করতে শুরু করতে আগ্রহী!
ইভান ওয়ান্ডার

0

আপনি এমনকি ব্রেস এক্সটেনশনগুলি ব্যবহার করতে পারেন:

mkdir -p directory{1..3}/subdirectory{1..3}/subsubdirectory{1..2}      
  • যা 3 ডিরেক্টরি (ডিরেক্টরি 1, ডিরেক্টরি 2, ডিরেক্টরি 3) তৈরি করে,
    • এবং তাদের প্রত্যেকের মধ্যে দুটি উপ-ডিরেক্টরি (উপ-ডিরেক্টরি 1, উপ-ডিরেক্টরি 2),
      • এবং তাদের প্রত্যেকটিতে দুটি সাব-ডাইরেক্টরি (সাব-ডাইরেক্টরি 1 এবং সাব-ডাইরেক্টরি 2)।

আপনাকে ব্যাশ 3.0.০ বা আরও নতুন ব্যবহার করতে হবে।


5
আকর্ষণীয়, তবে ওপি-র প্রশ্নের উত্তর দেয় না।
আলেক্সি ফিল্ড্যান্ডেল্ডার

0
$what=/path/to/file;
$dest=/dest/path;

mkdir -p "$(dirname "$dest")";
mv "$what" "$dest"

1
এটি একক শ স্ক্রিপ্ট তৈরি করতে, কেবল $ 1 এবং $ 2
ক্যাব 404

0

আমার এক স্ট্রিং সমাধান:

test -d "/home/newdir/" || mkdir -p "/home/newdir/" && mv /home/test.txt /home/newdir/

0

আপনি কমান্ডগুলি চেইন করতে পারেন: mkdir ~/bar/baz | mv foo.c ~/bar/baz/
বা শেল স্ক্রিপ্টটি এখানে রয়েছে:

#!/bin/bash
mkdir $2 | mv $1 $2

1. যে কোনও পাঠ্য সম্পাদক খুলুন
2. শেল স্ক্রিপ্ট অনুলিপি করুন
3. সংরক্ষণ এটি হিসাবে mkdir_mv.sh
লিখুন 4. আপনার স্ক্রিপ্টের ডিরেক্টরি: cd your/script/directory
5. পরিবর্তন ফাইল মোড : chmod +x mkdir_mv.sh
6. সেট ওরফে : alias mv="./mkdir_mv.sh"
এখন, যখনই আপনি নিম্নলিখিত কমান্ডটি প্রয়োগ mvচলন্ত ডিরেক্টরির যদি বিদ্যমান নয় তৈরি করা হবে।


0

অন্য উত্তরে একটি মন্তব্যের ভিত্তিতে, এখানে আমার শেল ফাংশন।

# mvp = move + create parents
function mvp () {
    source="$1"
    target="$2"
    target_dir="$(dirname "$target")"
    mkdir --parents $target_dir; mv $source $target
}

এটি .bashrc বা অনুরূপ অন্তর্ভুক্ত করুন যাতে আপনি এটি যে কোনও জায়গায় ব্যবহার করতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.