1

There are 4 user folders user1, user2, user3 and user4.

They all have music in their folder and I need to move these .mp4, .mkv and .mp3 files into the folder /tmp/Papierkorb

Also I need to rename it like, when user1 has a music file, it should change the name of the file into the name of the user_filename, from which user It comes from.

This is what I have now:

for file in $(find -type f -name *.mp3;find -type f -name *.mkv;find -type f -name *.mp4)
do
echo mv "$file" /tmp/Papierkorb$file;
done

This is what appears with echo:

root@ubuntu-VirtualBox:/home# bash script.sh 
mv ./user2/music/hits.mp3 /tmp/Papierkorb./user2/music/hits.mp3
mv ./user4/hits/music.mp3 /tmp/Papierkorb./user4/hits/music.mp3
mv ./user1/lied1.mp3 /tmp/Papierkorb./user1/lied1.mp3
mv ./user1/lied1.mkv /tmp/Papierkorb./user1/lied1.mkv
mv ./user1/lied12.mp4 /tmp/Papierkorb./user1/lied12.mp4
mv ./user1/1lied12.mp4 /tmp/Papierkorb./user1/1lied12.mp4
mv ./user3/test/meinealben/testlied.mp4 /tmp/Papierkorb./user3/test/meinealben/testlied.mp4

When I remove the echo, it says, that the folder after Papierkorb doesn't exist. I also don't know anything how I rename it into the name of the user, from which user the file comes from.

4
  • I assume that the error message is not Papierkorb does not exist, but Papierkorb. does not exist, with a dot at the end of the folder name. This can be fixed by adding a slash as in: /tmp/Papierkorb/$file. As for renaming files with username in them, I would rather use a separate folder for each user. Commented Jun 16, 2022 at 8:40
  • @mouviciel I did that, but there is also a dot somehow --- mv: cannot move './user2/music/hits.mp3' to '/tmp/Papierkorb/./user2/music/hits.mp3': No such file or directory Commented Jun 16, 2022 at 8:45
  • You have to create directories before moving files into them. Or you can move whole directories. More likely something in between: create user's directory, then move music and hits folders. Commented Jun 16, 2022 at 9:29
  • This is what I didn't wanted. I only need to move the files into that Papierkorb folder not their folders also. But I also realized later, that the folder got deleted while testing. Commented Jun 16, 2022 at 9:40

2 Answers 2

1

With find you can group the -name predicates and use the -exec ... {} + construct:

for user in user1 user2 user3 user4
do
    find "./$user" '(' -name '*.[mM][pP][34]' -o -name '*.[mM][kK][vV]' ')' -exec sh -c '
        for file
        do
            mv "$file" "$0${file##*/}"
        done
    ' "/tmp/Papierkorb/${user}_" {} +
done
Notes:
  • to make the code easier I used one find per username
  • the -exec sh -c '...' "/tmp/Papierkorb/${user}_" {} + is a little hackish but thanks to that you'll directly have value of /tmp/Papierkorb/${user}_ as $0 in the inline script
Sign up to request clarification or add additional context in comments.

3 Comments

find: paths must precede expression: `-' There is this error. Also where did you write it, that it should look for the music files mp3, mkv and mp4? Or is this code at find only for the name of the user?
There was a typo - o => -o; you tested the code before my edit
I realised the typo ^^ And also I now understand that mM,pP part and so on. So my question in the comments got answered. Thank you very much.
0

Using find and awk

#!/bin/bash

dir="/path/to/users"
# for all users
find "$dir" -maxdepth 2 -regex '.*\.\([mM][pP][34]\|[mM][kK][vV]\)'| \
awk -F/ '{print |"mv "$0" /tmp/Papierkorb/"$(NF-1)"_"$NF}'

# for some users
# using multiple find folders
find "$dir"/user1 "$dir"/user2 "$dir"/user3 -maxdepth 2 -regex '.*\.\([mM][pP][34]\|[mM][kK][vV]\)'| \
awk -F/ '{print |"mv "$0" /tmp/Papierkorb/"$(NF-1)"_"$NF}'

# using awk user filter 
find "$dir" -maxdepth 2 -regex '.*\.\([mM][pP][34]\|[mM][kK][vV]\)'| \
awk -F/ '/user1|user2|user3/ {print |"mv "$0" /tmp/Papierkorb/"$(NF-1)"_"$NF}'

# using awk condition
find "$dir" -maxdepth 2 -regex '.*\.\([mM][pP][34]\|[mM][kK][vV]\)'| \
awk -F/ '{if($(NF-1)=="user1" || $(NF-1)=="user2" print |"mv "$0" /tmp/Papierkorb/"$(NF-1)"_"$NF}'

Using find and xargs

find "$dir"/user1 "$dir"/user2 -maxdepth 2 -regex '.*\.\([mM][pP][3-4]\|[mM][kK][vV]\)'| \
xargs -i sh -c 'mv "{}" /tmp/Papierkorb/$(basename $(dirname "{}"))_$(basename "{}")'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.