Bash script, add one extention to it


Recommended Posts

Hey,

i use the following script to move 2 extentions into a f older. Now i found out, that i need mkv also moved.

 

Quote

 


#!/bin/bash
FROM_DIR=/mnt/user/downloads/completed/Filme
TO_DIR=/mnt/user/downloads/DVDR

FILES="$(find "$FROM_DIR" -iname '*.iso' -or -iname '*.img')"
for FILES in $FILES; do
    DIR="$(basename "$(dirname "$FILES")")"
    mkdir -p "$TO_DIR"/"$DIR"
    mv "$FILES" "$TO_DIR"/"$DIR"
done
 

 

 

i tried:

 

Quote

 


#!/bin/bash
FROM_DIR=/mnt/user/downloads/completed/Filme
TO_DIR=/mnt/user/downloads/DVDR

FILES="$(find "$FROM_DIR" -iname '*.iso' -or -iname '*.img' -or -iname '*.mkv')"
for FILES in $FILES; do
    DIR="$(basename "$(dirname "$FILES")")"
    mkdir -p "$TO_DIR"/"$DIR"
    mv "$FILES" "$TO_DIR"/"$DIR"
done
 

 

 

but that dont work...

 

 

mv: cannot stat '/mnt/user/downloads/completed/Filme/name(62+63)': No such file or directory
mv: cannot stat 'name': No such file or directory
mv: cannot stat 'name1': No such file or directory
mv: cannot stat 'name2': No such file or directory
mv: cannot stat 'DTS': No such file or directory
mv: cannot stat '5.1': No such file or directory
mv: cannot stat 'MKV': No such file or directory
mv: cannot stat 'h264': No such file or directory
mv: cannot stat '1080p': No such file or directory
mv: cannot stat 'German': No such file or directory
mv: cannot stat 'by': No such file or directory
mv: cannot stat 'name4': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat '5,39': No such file or directory
mv: cannot stat 'GB/name.mkv': No such file or directory
find: `/mnt/user/downloads/DVDR/Filme': No such file or directory
find: `/mnt/user/downloads/DVDR/GB': No such file or directory

 


I dont know how i can extent the list with ".mkv", i guess -or only takes 2 values, but how to do multiple?

Edited by nuhll
Link to comment
On 12/7/2018 at 8:46 PM, nuhll said:

I dont know how i can extent the list with ".mkv", i guess -or only takes 2 values, but how to do multiple?

Find can do multiples, but you need to wrap it with escaped parentheses for more than two "-or" operators.

I haven't tried it with your script so don't know how it interacts with the other variables and parentheses. I think it should work though.

find /mnt/user/downloads/completed/Filme \( -iname '*.iso' -or -iname '*.img' -or -iname '*.mkv' \)

So the actual script would look like this (again, I haven't tested it, try it on a test directory/files first!):

#!/bin/bash
FROM_DIR=/mnt/user/downloads/completed/Filme
TO_DIR=/mnt/user/downloads/DVDR

FILES="$(find "$FROM_DIR" \( -iname '*.iso' -or -iname '*.img' -or -iname '*.mkv' \))"
for FILES in $FILES; do
    DIR="$(basename "$(dirname "$FILES")")"
    mkdir -p "$TO_DIR"/"$DIR"
    mv "$FILES" "$TO_DIR"/"$DIR"
done

 

Alternatively, you could use find with regex instead of "-or" operators, might be easier if you have lots of extensions to add:

FILES="$(find "$FROM_DIR" -regextype posix-egrep -regex '.*\.(iso|img|mkv)$')"

 

 

Link to comment

Hi thank youi for your help, sadly its not working:

 

1. script

mv: cannot stat '/mnt/user/downloads/completed/Filme/name(62+63)': No such file or directory
mv: cannot stat 'name': No such file or directory
mv: cannot stat 'name': No such file or directory
mv: cannot stat '2002': No such file or directory
mv: cannot stat 'DTS': No such file or directory
mv: cannot stat '5.1': No such file or directory
mv: cannot stat 'MKV': No such file or directory
mv: cannot stat 'h264': No such file or directory
mv: cannot stat '1080p': No such file or directory
mv: cannot stat 'German': No such file or directory
mv: cannot stat 'by': No such file or directory
mv: cannot stat 'name+22.PAR2': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat '5,39': No such file or directory
mv: cannot stat 'GB/name.mkv': No such file or directory
mv: cannot stat '/mnt/user/downloads/completed/Filme/name': No such file or directory
mv: cannot stat 'franky007': No such file or directory
dirname: invalid option -- '/'
Try 'dirname --help' for more information.
mv: invalid option -- '/'
Try 'mv --help' for more information.
mv: cannot stat '/mnt/user/downloads/completed/Filme/name': No such file or directory
mv: cannot stat 'name': No such file or directory
dirname: invalid option -- '/'
Try 'dirname --help' for more information.
mv: invalid option -- '/'
Try 'mv --help' for more information.
mv: cannot stat '/mnt/user/downloads/completed/Filme/name': No such file or directory
mv: cannot stat 'franky007/name.mkv': No such file or directory
find: `/mnt/user/downloads/DVDR/Filme': No such file or directory
find: `/mnt/user/downloads/DVDR/GB': No such file or directory
find: `/mnt/user/downloads/DVDR/franky007': No such file or directory

 

2. has similiar output

 

I think its the syntax:

 

root@Unraid-Server:~# find /dir/Filme -regextype posix-egrep -regex '.*\.(iso|img|mkv)$')
-bash: syntax error near unexpected token `)'
root@Unraid-Server:~# find /dir/Filme -regextype posix-egrep -regex '.*\.(iso|img|mkv)$'
/mnt/user/downloads/completed/Filme/name.mkv
/mnt/user/downloads/completed/Filme/name1.mkv
/mnt/user/downloads/completed/Filme/name3.mkv
/mnt/user/downloads/completed/Filme/name4.mkv

Edited by nuhll
Link to comment

I tested both now, they work and give the directory + filename.

 

I guess it needs to be " " ' '  or something because it takes every part as path instead of the whole line, you know what i mean?

 

like it takes from

 

this/is/a/dir

 

it does it for /this/ and /is/ and /a/ and /dir/ instead of "/this/is/a/dir"

 

btw, thats all of that script, it just needs to put DVDR files into the automatic folder for transcoding to normal files.

 

Thats why its important that it keeps the /DIRECTORYNAME/FILENAME ...^^

Edited by nuhll
Link to comment

Yeah, I’m out of my depth here, but I think you’re right that you need to enclose the path with double quotes somewhere. Although it looks like the script is doing that already.

Just to confirm I understood your use case correctly. You want the script to:
1. identify all files with a certain extension in the source directory
2. create a sub-directory in the source directory with the name of the found file
3. move the file into the new sub-directory

For step 1, are the files always in the root of the source directory? Or are they buried in multiple levels of sub folders?
If they are in sub-folders, you don’t want that folder structure replicated?




Sent from my iPhone using Tapatalk

  • Like 1
Link to comment

1. yes.

 

 

How its archived i dont care. But i need the files with the extention "XXX", "XXX2", "XXX3" with parent folder moved to another path :)

 

The current script reads the current parent directory and then creates it in the "OUTPUT directory"

 

 

SOURCEDIRECTORY/MOVIENAME/MOVIENAME.MKV

 

->


OUTPUT/MOVIENAME/MOVIENAME.MKV

 

thats all :) how thats archived i dont care 😆

 

 

Thank you for all your help so far!

 

 

.... could it be that the last find command didnt print out the exact directory.. and the new command does that? Because then, the whole basename thing and so on is complete useless and double

Edited by nuhll
Link to comment
4 hours ago, nuhll said:

.... could it be that the last find command didnt print out the exact directory.. and the new command does that? Because then, the whole basename thing and so on is complete useless and double 

2

Maybe, but I don't think so. To test, run these two commands and compare the output:

find "/mnt/user/downloads/completed/Filme" -iname '*.iso' -or -iname '*.img'

find "/mnt/user/downloads/completed/Filme" \( -iname '*.iso' -or -iname '*.img' -or -iname '*.mkv' \)

 

Link to comment

Ok, the two find commands return identical lists, so that's not it.

The problem is this:

The $FILES list is using spaces as delimiters, which is also used in the "for in do" loop

This only works as long as none of the paths in the list contains spaces

If they do, you get the errors you are seeing.

Your original script have the same problem, so I guess you must have never run it over files containing spaces before?

 

One fix is to use find -exec instead of a "for in do" loop on the find result. I'm not skilled enough to write that though, but here are some hints if you want to give it a crack: https://stackoverflow.com/questions/301039/how-can-i-escape-white-space-in-a-bash-loop-list

 

Another way to achieve the same thing is to use rsync instead of find. The drawback is that this is actually a copy-then-delete operation, so will be slower than using mv.

 

This script should work for you:

#!/bin/bash
FROM_DIR="/mnt/user/downloads/completed/Filme"
TO_DIR="/mnt/user/downloads/DVDR"

rsync -ar --include '*/' --include '*.iso' --include '*.img' --include '*.mkv' --exclude '*' --remove-source-files --prune-empty-dirs --progress "$FROM_DIR/" "$TO_DIR"
find "$FROM_DIR/" -depth -empty -type d -delete # This removes empty directories in the source directory

Folder structure before running the script in my test (I used slightly different paths compared to you):

downloads/
├── DVDR
└── completed
    ├── movie with spaces
    │   └── movie with spaces.iso
    ├── movie1
    │   └── movie1.iso
    ├── movie2
    │   └── movie2.img
    ├── movie3
    │   └── movie3.mkv
    ├── movie4
    │   └── movie4.avi
    ├── movie5.avi
    └── movie6.mkv

And after running the script:

downloads/
├── DVDR
│   ├── movie with spaces
│   │   └── movie with spaces.iso
│   ├── movie1
│   │   └── movie1.iso
│   ├── movie2
│   │   └── movie2.img
│   ├── movie3
│   │   └── movie3.mkv
│   └── movie6.mkv
└── completed
    ├── movie4
    │   └── movie4.avi
    └── movie5.avi

You can see that it has moved all .iso. img. and .mkv files, while leaving .avi in place, and retaining the folder sturcutre form the source directory.

Note that movie6.mkv was in the root of the source directory, and therefore ended up in the root of the destination DVDR folder. The script only retains existing parent folders, it doesn't create new ones. Hope that works for you.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.