Linux move file create directory

Is there a one-liner that allows me to create a directory and move into it at the same time?

I know the OP says bash, but others who find this via Google like me might be interested to know that Oh My Zsh has mkcd as a built-in function.

12 Answers 12

This is the one-liner that you need. No other config needed:

mkdir longtitleproject && cd $_ 

The $_ variable, in bash, is the last argument given to the previous command. In this case, the name of the directory you just created. As explained in man bash :

_ At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the envi‐ ronment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When check‐ ing mail, this parameter holds the name of the mail file cur‐ rently being checked."$_" is the last argument of the previous command. 

Use cd $_ to retrieve the last argument of the previous command instead of cd !$ because cd !$ gives the last argument of previous command in the shell history:

cd ~/ mkdir newfolder && cd $_ 

you end up in newfolder under home !! ( or ~/newfolder )

I think the OP is trying to avoid using the two commands. This answer is (almost) as valid as doing mkdir foo && cd foo , which isn’t handy.

This is the traditional one-liner you are referring to or have seen others use in docs/tutorials. There are actually 3 perfect answers here. This one, the one by @jordan-harris , and the selected answer. Depends on your setup and preference.

By the upvotes it’s evident many people are finding this answer useful. I’ll state why I didn’t select this answer: I’m very likely to mistype && cd $_ since the keys are so far away from the home row, so while technically correct, it’s not ergonomic. I appreciate the fact that it’s not environment dependent and it’s useful to know. Thanks!

There’s no built-in command, but you can easily write a function that calls mkdir then cd :

Put this code in your ~/.bashrc file (or ~/.kshrc for ksh users, or ~/.zshrc for zsh users). It defines a function called mkcd . «$1» will be replaced by the argument of the function when you run it.

This simple version has several defects:

  • You cannot create a chain of subdirectories at once. Fix: pass the -p option to mkdir . (This may or may not be desirable, as it increases the risk of a typo going undetected, e.g. mkcd mydierctory/newsub will happily create mydierctory and mydierctory/newsub when you meant to create newsub inside the existing mydirectory .)
  • If the argument begins with — but isn’t just — , then mkdir and cd will interpret it as an option. If it’s just — , then cd will interpret it to mean $OLDPWD . If it’s + followed by 0 or more digits, then cd in zsh will interpret it as an index in the directory stack. You can fix the first problem, but not the other two, by passing — before the argument. You can fix all of these problems by prepending ./ to the argument if it’s a relative path.
  • mkdir doesn’t follow CDPATH , but cd does, so if you’ve set CDPATH to a value that doesn’t begin with . (an admittedly somewhat unusual configuration), then cd may bring you to a different directory than the one that was just created. Prepending ./ to relative paths fixes this¹ (it causes CDPATH to be ignored).
  • If mkdir fails, it tries to execute cd . Fix: use && to separate the two commands.
Читайте также:  Интегрированные среды разработки linux

This version still has the potential to make cd go into a different directory from the one that mkdir just created in one edge case: if the argument to mkcd contains .. and goes through a symbolic link. For example, if the current directory is /tmp/here and mylink is a symbolic link to /somewhere/else , then mkdir mylink/../foo creates /somewhere/foo whereas cd mylink/../foo changes into foo (which is /tmp/here/foo ). It’s not enough to look for symbolic links in the argument, because the shell also tracks symbolic links in its own current directory, so cd /tmp/mylink; mkdir ../foo; cd ../foo does not change into the new directory ( /somewhere/else/foo ) but into /tmp/foo . A fix for this is to let the cd builtin resolve all .. path components first (it doesn’t make sense to use foo/.. if foo doesn’t exist, so mkdir never needs to see any .. ).

We come to this robust if slightly gory version:

mkcd () < case "$1" in */..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists /*/../*) (cd "$/.." && mkdir -p "./$") && cd -- "$1";; /*) mkdir -p "$1" && cd "$1";; */../*) (cd "./$/.." && mkdir -p "./$") && cd "./$1";; ../*) (cd .. && mkdir -p "$") && cd "$1";; *) mkdir -p "./$1" && cd "./$1";; esac > 

(Exercise: why am I using a subshell for the first cd call?)

If mkdir fails, I want to be sure not to change the current directory. Changing back with cd — or $OLDPWD isn’t good enough if the shell doesn’t have permission to change into its current directory. Also, calling cd updates OLDPWD, so we only want to do it once (or restore OLDPWD).

There are also less specialized ways to not have to retype the word from the previous line:

  • Type cd , then Esc . (or Alt + . ) to insert the last argument from the previous command.
  • cd !$ executes cd on the last argument of the previous command.
  • Press Up to recall the previous command line, then edit it to change mkdir into cd .

¹ beware however that it doesn’t work in ksh93 since the u+ version, fixed in 93u+m/1.0.0-alpha+d1483150 2021-01-05

Читайте также:  Восстановление корневой файловой системы linux

Источник

mv command creates directories [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.

This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.

I am facing a very weird issue. Consider an example I have these directories «/ten» and «/one/two/three/four» I have a few files in these directories. When i execute the following command

mv /ten/ /one/two/three/four/five/six 

it gives the output as mv: cannot move ‘/ten/’ to ‘/one/two/three/four/five/six’ : No such file or directory. Which looks fine as it doesn’t create directories. But if I execute the following command

mv /one/two/three/four/ /one/two/five/six 

the directories five/six get created inside /one/two. i.e. the mv command succeeds. Can anyone please explain what is happening here ? Why doesn’t it give an error No such file or directory ? EDIT : Further Observation .. Directories /one/two/three/four exists also directories /one/two/five exists. Executing mv /one/two/three/four/ /one/two/five/six will succeed. Here directory six will get created even though it is not present.
This doesn’t happen in the case when I execute mv /one/two/three/four /one/two/five/six and the «five» directory doesn’t exists. In this case it will give error. I thought mv will never create any directories. Please let me know if I have missed something obvious.

Источник

Will `mv` ever have the ability to create directories?

This question asks for the best way to create a directory when using mv if it doesn’t exist. My question is why isn’t this an inbuilt feature of mv ? Is there some fundamental reason due to which this would not be a good idea?

I think there is no fundamental reason for it. It is just the design — do one thing and do it well. It’s on old Unix school. Use mkdir to create directories, rm to remove them, mv to move them.

It could be just an old Unix convention, which was then standardized by the POSIX standard. Changing it would create incompatibilities in scripts where the old behaviour (fail if target directory does not exists) is expected.

@Jofel, it could be alleviated with a flag, like mv -d or something else to force create a directory, so the scripts with old behaviour will not be affected.

1 Answer 1

Keep in mind that there is more than one implementation of mv . The mv you use on linux is not from the exact same source as the one on OSX or Solaris, etc. But it is desirable for them all to behave in the same way — this is the point of standards. It’s conceivable that a mv implementation could add an option for this purpose, although since it is so simple to deal with, it would probably not be worthwhile because the very minor benefit is outwayed by a more significant negative consequence: Code written which exploited such a non-standard option of an implementation would not be portable to/behave constantly on another system using a standard implementation.

Читайте также:  Use system default window controls linux

mv is standardized by POSIX and this explicitly ties its behavior to the rename() system call. In ISO C the behavior of rename() is not very specific and much is left up to the implementation, but under POSIX you’ll note the potential ENOENT error, indicating «a component of the path prefix of new does not exist», describing the behavior to be expected in explicit terms. This is better than ambiguity and leaving such details up to the implementation, because doing the latter hurts the portability.

In defense of the design, in a scripting context it’s probably better to by default fail on an invalid target path than assume it just needs to be created. This is because the path itself may often come from user input or configuration and may include a typo; in this case the script should fail at that point and indicate to the user that they’ve entered an invalid path. There is of course the option for the person who wrote the code to implement different behavior and create directories that don’t exist, but it is better that you are responsible for doing that than the opposite (being responsible for ensuring a mv call won’t create previously non-existent directories).

Источник

linux bash script to create folder and move files

Hello I need to create folder based on a filename and in this folder create another one and then move file to this second folder example:
my_file.jpg
create folder my_file
create folder picture
move my_file.jpg to picture I have this script but it only works on windows and now I’m using Linux

for %%A in (*.jpg) do mkdir "%%~nA/picture" & move "%%A" "%%~nA/picture" pause 

3 Answers 3

#!/usr/bin/env bash # Enable bash built-in extglob to ease file matching. shopt -s extglob # To deal with the case where nothing matches. (courtesy of mklement0) shopt -s nullglob # A pattern to match files with specific file extensions. # Example for matching additional file types. #match="*+(jpg|.png|.gif)" match="*+(.jpg)" # By default use the current working directory. src="https://stackoverflow.com/questions/22668866/$%3C1:-.%3E" dest="$" # Pass an argument to this script to name the subdirectory # something other than picture. subdirectory="$" # For each file matched for file in "$"/$match do # make a directory with the same name without file extension # and a subdirectory. targetdir="$/$(basename "$")/$" # Remove echo command after the script outputs fit your use case. echo mkdir -p "$" # Move the file to the subdirectory. echo mv "$file" "$" done 

Thank You mate but where do I need to put destination folder, all my files are in /root/Desktop/My_pictures I tried to add command where this script should look my .jpg files but with no luck

Nicely done; a simpler alternative to extglob in this case is to use for file in *.jpg *.png *.gif (although you need to deal with the case where nothing matches, e.g. with shopt -s nullglob ). Better not to use all-caps variable names to avoid conflicts with environment variables — see stackoverflow.com/a/673940/45375

All of your jpg files are in /root/Desktop/My_pictures currently? Where do you want them to be? Do you want to pass arguments to script or have the destination in the script?

Источник

Оцените статью
Adblock
detector