2

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

Sorry if I'm not precise but English is not my native language.

P̲̳x͓L̳
  • 3,615
  • 3
  • 29
  • 37
Peter_
  • 72
  • 1
  • 5

3 Answers3

3

Use basename to create the directory name, mkdir to create the folder, and mv the file:

for file in *.jpg; do
  folder=$(basename "$file" ".jpg")"/picture"
  mkdir -p "$folder" && mv "$file" "$folder"
done
devnull
  • 118,548
  • 33
  • 236
  • 227
  • Don't you mean `basename "$file" ".jpg"` (path first, then suffix)? – mklement0 Mar 26 '14 at 19:56
  • @mklement0 Thanks. I can't believe that I typed that and it was upvoted too! – devnull Mar 26 '14 at 19:59
  • :) That may be due to the gravitas that comes with ~35k. – mklement0 Mar 26 '14 at 20:00
  • Isn't the intent to *strip* the suffix (extension), e.g. `someFile.jpg` -> `someFile`? The syntax is `basename NAME SUFFIX` (at least on Linux and OSX). Try `basename "someFile.jpg" ".jpg"` vs. `basename ".jpg" "someFile.jpg"` – mklement0 Mar 26 '14 at 20:10
  • 1
    @mklement0 And your point about _gravitas_ isn't perhaps invalid. In some other tags, you'd need multiple upvotes within a matter of seconds. (Those are _legends_, 200k+ or so. `:)`) – devnull Mar 26 '14 at 20:15
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="${1:-.}"
dest="${2:-/root/Desktop/My_pictures/}"

# Pass an argument to this script to name the subdirectory
# something other than picture.
subdirectory="${3:-picture}"

# For each file matched
for file in "${src}"/$match
do
  # make a directory with the same name without file extension
  # and a subdirectory.
  targetdir="${dest}/$(basename "${file%.*}")/${subdirectory}"
  # Remove echo command after the script outputs fit your use case. 
  echo mkdir -p "${targetdir}"
  # Move the file to the subdirectory.
  echo mv "$file" "${targetdir}"
done
mjmcull
  • 60
  • 5
  • 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 – Peter_ Mar 26 '14 at 20:27
  • 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 http://stackoverflow.com/a/673940/45375 – mklement0 Mar 26 '14 at 20:52
  • 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? – mjmcull Mar 26 '14 at 21:01
  • Thank you for the tip mklement0 – mjmcull Mar 26 '14 at 21:04
  • Yes all my files are in /root/Desktop/My_pictures and I want them there, You can add destination in the script for example picture "cat.jpg" /root/Desktop/My_pictures/cat/pictures/cat.jpg – Peter_ Mar 26 '14 at 21:06
  • This will look for jpg files in the current working directory unless you give it a directory as an argument and move them to /root/Desktop/My_pictures/ by default. Hope it helps. – mjmcull Mar 26 '14 at 21:38
  • +1 for pound bang env, echo instead of doing immediately, and all the comments. – bishop Mar 27 '14 at 00:01
  • My pleasure; if you want to default to the current dir., you probably want to use `src="${1:-.}"`, not `src="${1:-}"`, otherwise `"{$src}"/$match` will default to matching in `/`; also, you need to use `basename "${file%.*}"` in the `mkdir` command as well - probably better to assign to a variable first: `targetdir="${dest}/$(basename "${file%.*}")/${subdirectory}"` – mklement0 Mar 27 '14 at 01:52
  • Thanks again mklement0. I originally had a . but tested it without and with no change in result. Better safe than sorry. – mjmcull Mar 27 '14 at 11:45
2

Try the following:

for f in *.jpg; do
    mkdir -p "${f%.jpg}/picture"
    mv "$f" "${f%.jpg}/picture"
done

${f%.jpg} extracts the part of the filename before the .jpg to create the directory. Then the file is moved there.

Elmar Peise
  • 14,014
  • 3
  • 21
  • 40