Home > OS >  Bash move files and rename it as username_filename in a different folder
Bash move files and rename it as username_filename in a different folder

Time:06-17

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.

CodePudding user response:

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

CodePudding user response:

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 "{}")'
  • Related