make a folder for each file in a directory then move the file into it
Initially I thought - piece of piss, use a for loop with ls in it:
Code:
for file in `ls /shares/ | egrep -v '(.srt|.ass|.sub)'; do mkdir $files && mv $files /shares/$files/; done; The contents of the folder is basically movies (some with subtitles). Some of the names have things like (original) or CD1 CD2 in them. Any ideas? |
Quote:
Code:
shopt -s extglob |
Quote:
-sh: shopt: not found ~ # which shopt ~ # I'm using a very minimal kernel... Find might do it though :) |
The part about duplicate folders makes me think that there are already folders in the folder / directory you are looking into?
Hence the for solution is incomplete unless you check each one that is found as to whether or not it is a file. The other issue you have as well is that in linux all items are considered files at their base and just have an identifier to say they are something else like a directory (simplistic but you get the point). So, if for example you have a file called test.txt, you can no longer make in the same directory a file, of any type, with the same name. Try this simple test: Code:
$ touch test.txt Quote:
Hope that gives you some ideas. |
I didn't actually mean 'duplicate' folders. I end up with folders such as "/shares/allaboutlinuxCD1.avi/" "/shares/allaboutlinuxCD2.avi/".
The idea is that for every file with a similar name it needs to reside in a folder named after the bits of their name that are similar (minus the extension). What I REALLY want is something with the following structure: Code:
/shares/allaboutlinux Code:
ls -l |
So I am not sure I have said this to you before, although I have said it many times on this site, ls is most definitely not to be used as a general rule of thumb (see here for why not)
One of the main reasons which would definitely affect you in this scenario is that the for loop will perform word splitting on the output (which you have already run into with titles with spaces in the names) ntubski's use of globbing does overcome this but you still face the issue of testing for directories and so on. You have now added a further layer of complexity which I believe you would need to handle first which is the option of having multiple files needing to go into a new single directory. To this end I would probably generate a temp file with the output of all files and then use your favourite tool on the file to create the list of names for the new directories. Another possible solution which just popped into my head. Use your initial idea to create all the directories and instead of using the full name, create a directory with the extension removed. This solves the issue of creating temp directories or files and then you only need to create a small number of moves and copies to tidy up the extras you want moved. What do you think? I think you could easily manage the second one :) |
I'll have a toy with it, pity there's not an alternative to using ls for a task like this (using tr to replace spaces outside the loop and then using tr to replace *with* spaces inside the loop). Thanks for all your ideas :)
|
Quote:
If you follow the link you will see that in the general scheme of things, unless you are simply listing items to be read by a human then ls is generally the one tool not to use. |
Sorry. Didn't read the post properly.
|
Quote:
Code:
|
hmmm ... not so sure about this one ntubski. Normally I follow but you lost me on:
Code:
dir=$(echo "$file" | sed 's/[A-Z0-9]*\..*$//;s/ //g') I would also like to point out that the regex in the find did not work for me. According to the man page, regex for find requires the entire path to be matched, so you would need a further .* at the beginning. Code:
find /shares -maxdepth 1 ! -regex '.*\.\(srt\|ass\|sub\)$' -type f |
Quote:
Code:
$ echo "/shares/all about linux CD1.avi" | sed 's/[A-Z0-9]*\..*$//;s/ //g' Quote:
|
Quote:
I would however caution OP on the fact that if you have dot separated names that this will currently remove everything after the first dot. Also, you may have issues if your filenames are capitalising first letter of each word: Code:
/share/All About Linux CD1.avi |
Thanks for all your help, I'll run some tests and see what is best suited to my media (my media does have a capital for each first letter most of the time and special characters...). The kernel is incredibly basic, so I'm not entirely sure all of these commands will work, but I'll give it a shot. It's basically one of those NAS boxes; I've already noticed find to be lacking most of the common arguements.
If none of these solutions work I may mount this share point on a different linux box and run the above code. Failing that I'll probably try using some free Windows tool (my /shares folder is exported as a CIFS share anyway). |
Quote:
Code:
~$ echo "/shares/All About Linux CD1.avi" | sed 's/[A-Z0-9]*\..*$//;s/ //g' Quote:
|
All times are GMT -5. The time now is 01:49 AM. |