Linux: how to move each file to a folder with the corresponding name

I have a small but interesting task here. I have a list of files with the same extension, for example.

a.abc b.abc c.abc 

I want here to first create folders named a , b , c ... for each .abc file, and then move them to my folder.

I managed to take the first step quite simply using the line cmd find ... | sed ... | xargs mkdir... find ... | sed ... | xargs mkdir... find ... | sed ... | xargs mkdir... but when I tried to use a similar cmd to move each file to its own folder, I could not find the answer.

I donโ€™t own CMD here, and I have very fuzzy memory, that in find cmd I can use some backlink to reuse the file / directory name, donโ€™t I remember it wrong? Searched for it, but did not find a good link.

Can someone help me fill in cmd here?

Thanks.

+4
source share
3 answers

Here is your one liner

 find . -name "*.abc" -exec sh -c 'NEWDIR=`basename "$1" .abc` ; mkdir "$NEWDIR" ; mv "$1" "$NEWDIR" ' _ {} \; 

or alternatively

 find . -name "*.abc" -exec sh -c 'mkdir "${1%.*}" ; mv "$1" "${1%.*}" ' _ {} \; 

And this is a better guide to using find than the man page.

This page explains the parameter extension that occurs (to understand ${1%.*}

+14
source

Here is a find and xargs solution that handles file names with spaces:

 find . -type f -print0 | xargs -0 -l sh -c 'mkdir "${1%.*}" && mv "$1" "${1%.*}"' sh 

Please note that it does not support file names with newlines and / or shell extensible characters.

+5
source
 for F in /tmp/folder/*.abc # replace by $1 for first arg do BASE="${F%.abc}" mv "$F" "$BASE" done 
+2
source

All Articles