简体   繁体   中英

moving files from a folder into subfolders based on the prefix number with Linux

I'm relatively new to bash and I have tried multiples solutions that I could find here but none of them seem to be working in my case. It's pretty simple, I have a folder that looks like this:

- images/
   - 0_image_1.jpg
   - 0_image_2.jpg
   - 0_image_3.jpg
   - 1_image_1.jpg
   - 1_image_2.jpg
   - 1_image_3.jpg

and I would like to move these jpg files into subfolders based on the prefix number like so:

- images_0/
   - 0_image_1.jpg
   - 0_image_2.jpg
   - 0_image_3.jpg

- images_1/
   - 1_image_1.jpg
   - 1_image_2.jpg
   - 1_image_3.jpg

Is there a bash command that could do that in a simple way? Thank you

for src in *_*.jpg; do
  dest=images_${src%%_*}/
  echo mkdir -p "$dest"
  echo mv -- "$src" "$dest"
done

Remove both echo s if the output looks good.

I would do this with rename aka Perl rename . It is extremely powerful and performant. Here's a command for your use case:

rename --dry-run -p '$_="images_" . substr($_,0,1) . "/" . $_'  ?_*jpg

Let's dissect that. At the right end, we specify we only want to work on files that start with a single character/digit before an underscore so we don't do damage trying to apply the command to files it wasn't meant for. Then --dry-run means it doesn't actually do anything, it just shows you what it would do - this is a very useful feature. Then -p which handily means "create any necessary directories for me as you go" . Then the meat of the command. It passes you the current filename in a variable called $_ and we then need to create a new variable called $_ to say what we want the file to be called. In this case we just want the word images_ followed by the first digit of the existing filename and then a slash and the original name. Simples!

Sample Output

'0_image_1.jpg' would be renamed to 'images_0/0_image_1.jpg'
'0_image_2.jpg' would be renamed to 'images_0/0_image_2.jpg'
'1_image_3.jpg' would be renamed to 'images_1/1_image_3.jpg'

Remove the --dry-run and run again for real, if the output looks good.

Using rename has several benefits:

  • that it will warn and avoid any conflicts if two files rename to the same thing,
  • that it can rename across directories, creating any necessary intermediate directories on the way,
  • that you can do a dry run first to test it,
  • that you can use arbitrarily complex Perl code to specify the new name.

Note : On macOS , you can install rename using homebrew :

brew install rename

Note : On some Ones, rename is referred to as prename for Perl rename .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM