LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 02-18-2009, 08:40 AM   #1
Ztyx
Member
 
Registered: Dec 2001
Location: Stockholm, Sweden
Distribution: Ubuntu, Kubuntu and Debian
Posts: 338

Rep: Reputation: 30
Move file and change directory in one command


Hi,

I am a UNIX/Linux users since ten years back and I've been using the terminal (BASH) almost daily since then.

One thing that has always annoyed me is the lack of a command to move a file (mv) to a directory and then immediately cd (ie. change directory) to that same destination. This would be a very nifty command saving both my time and wrists!

Example:
Code:
arnold@computer:~/path$ mkdir newpath
arnold@computer:~/path$ touch newfile
arnold@computer:~/path$ mvcd newfile newpath
arnold@computer:~/path/newpath$
Now, from the little I know about BASH programming I could either write a script or use aliasing.

Using a script would not, as I see it, work because changing directory withing the script would only change current directory within the script and not outside in my terminal instance.

Writing an alias I am not sure would be possible unless some parameter magic can be done within the alias functionality.

Is there anyone who has got the slightest idea to take on this silly little quest?

Thanks Jens
 
Old 02-18-2009, 08:56 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Arch/XFCE
Posts: 17,802

Rep: Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728Reputation: 728
You can:
1. Write a script
2. Use ";"
 
Old 02-18-2009, 09:44 AM   #3
Ztyx
Member
 
Registered: Dec 2001
Location: Stockholm, Sweden
Distribution: Ubuntu, Kubuntu and Debian
Posts: 338

Original Poster
Rep: Reputation: 30
1. A script does not work because the $PWD is local to the script. A child process cannot export variables back to the parent processes that spawned them.
2. Elaborate. I cannot see how using a ';' would yield anything useful in this case as long as it was possible to extract the parameters when using aliasing.

Last edited by Ztyx; 02-18-2009 at 09:45 AM.
 
Old 02-18-2009, 10:06 AM   #4
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,490

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
Another possibility is to define a function in your .bashrc. It can be something like this:
Code:
function mvc(){
  num_of_files=$(($# - 1))
  for i in $(eval echo {1..$num_of_files})
  do
    eval mv \$$i \$$#
  done
  eval cd \$$#
}
For example:
Code:
$ pwd
/home/colucix/source
$ ls
file1  file2  file3
$ mvc file* ../dest
$ pwd
$ /home/colucix/dest
$ ls
$ file1  file2  file3
$
 
Old 02-19-2009, 02:40 AM   #5
Ztyx
Member
 
Registered: Dec 2001
Location: Stockholm, Sweden
Distribution: Ubuntu, Kubuntu and Debian
Posts: 338

Original Poster
Rep: Reputation: 30
Thanks! A few simple modifications and this works like a charm:
Code:
function mvcd {
  mv $*
  eval last=\$$#
  cd $last
}
(just put in .bashrc and the mvcd command works next time you start BASH)

Thanks again!

Jens

Last edited by Ztyx; 02-19-2009 at 02:41 AM. Reason: Bad syntax
 
Old 02-19-2009, 02:49 AM   #6
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,490

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
Very good! Indeed no need to loop over files. Well done!
 
Old 02-19-2009, 03:40 AM   #7
theYinYeti
Senior Member
 
Registered: Jul 2004
Location: France
Distribution: Arch Linux
Posts: 1,897

Rep: Reputation: 61
Not so sure. Up to 8 files to move, I think this would work, but beyond that, the 9-parameters limit is reached and the script fails. This should work:
Code:
function mvcd {
  mv "$@"
  while [ $# -gt 1 ]; do shift; done
  cd "$1"
}
Example:
Code:
$ function test() {
> echo number: $#
> eval last=\$$#
> echo last: $last
> }
$ test un deux trois quatre cinq six sept huit neuf dix onze douze
number: 12
last: un2
$ function test() {
> echo number: $#
> while [ $# -gt 1 ]; do shift; done
> echo last: $1
> }
$ test un deux trois quatre cinq six sept huit neuf dix onze douze
number: 12
last: douze
Yves.
 
Old 02-19-2009, 04:05 AM   #8
Valery Reznic
ELF Statifier author
 
Registered: Oct 2007
Posts: 666

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by theYinYeti View Post
Not so sure. Up to 8 files to move, I think this would work, but beyond that, the 9-parameters limit is reached and the script fails. This should work:
Code:
function mvcd {
  mv "$@"
  while [ $# -gt 1 ]; do shift; done
  cd "$1"
}
While it works, I think 'mv "$@"' may be dangerous one. OK, not more dangerous then 'mv' itself, but still... Some time ago I intended to do following:

Code:
   mv *.c some_dir
But I was too quick, and instead I did
Code:
   mv *.c
Usually mv refuse do it:
Code:
mv: target `XXX' is not a directory
But unfortunately I had only two .c files, so it became
Code:
mv a.c b.c
And of course mv was just happy to overwrite b.c

So as precaution:
Code:
function mvcd {
  if [ $# -ne 2 -o -d $2 ] then
     mv "$@"
     while [ $# -gt 1 ]; do shift; done
     cd "$1"
  else
     echo "Last argument should be directory" 1>&2
     return 1
  fi
}
 
Old 02-19-2009, 04:09 AM   #9
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,490

Rep: Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956Reputation: 1956
Yves, you are right! Thanks for notice. However in bash you can avoid the problem using brackets to envelop positional parameters greater than 9. So, following the example I posted above, this version should work
Code:
function mvc () 
{ 
     num_of_files=$(($# - 1))
     for i in $(eval echo {1..$num_of_files})
     do
         eval mv \${$i} \${$#}
     done
     eval cd \${$#}
}
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can you move a file or directory and still retain mtime? ddenton Linux - General 3 11-21-2008 04:54 PM
Why won't it let me copy or move a file from one directory to another? dewjunkie Linux - Newbie 4 01-23-2008 12:31 AM
how do i get permission to move file into directory timalan Suse/Novell 2 08-24-2005 09:25 PM
Move file command? oldrelac Linux - Newbie 10 08-08-2003 11:58 AM
Is it possible to move file from /dev to other directory? raindrop Linux - Hardware 2 11-13-2002 05:37 PM


All times are GMT -5. The time now is 05:13 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration