Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux: how to move each file into a correspondingly named folder

Tags:

linux

shell

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

a.abc
b.abc
c.abc

What I want here is to first create folders called a, b, c... for each .abc file, and then move each one into its folder.

I was able to get the first step done pretty straightforwardly using a cmd line find ... | sed ... | xargs mkdir..., but when I tried to use a similar cmd to move each file into its own folder, I couldn't find the answer.

I'm not fluent with the cmd here, and I have a very fuzzy memory that in find cmd I can use some kind of back reference to reuse the file/directory name, did I remember it wrong? Searched it up but couldn't find a good reference.

Can anyone help me to complete the cmd here?

Thanks.

like image 730
Derek Avatar asked Aug 14 '12 22:08

Derek


2 Answers

Here's 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 at using find than the man page.

This page explains the parameter expansion that is going on (to understand the ${1%.*}

like image 119
twmb Avatar answered Nov 09 '22 23:11

twmb


Here is a find and xargs solution which handles filenames with spaces:

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

Note that it does not support filenames with newlines and/or shell-expandable characters.

like image 35
Thor Avatar answered Nov 09 '22 22:11

Thor