I did it in two commands --- one for splitting, and one for moving. I can't seem to find my way around it such as to have it all done with one line. What I did was:

split.exe --bytes=2300k -d 01_somefile.mp3 01_somefile.mp3

to get 01_somefile.mp301, 01_somefile.mp302, 01_somefile.mp303, and so on. Then

for file in *0?; do mv "$file" "$file.mp3"; done

to have them all back as mp3.

I would appreciate if someone could help me with an one liner for this that loops through the directory and does this splitting and renaming. I am still poor with the commands. I've tried this:

for file in *.MP3; do split.exe --bytes=2500k -d "$file" "$file" && mv "$file" "$file".mp3; done

I want to ask how can I control the name of the resulting pieces. Say, I have this file in the dir: 01_dickens_copperfield.mp3, next to 02.dickens_copperfield.mp3 and so on. I'm still finding them large and want them broken to other pieces and finally, want them renamed as .mp3


for file in *.MP3; do split.exe --bytes=2500k -d "$file" "$file"; done

produces the files 01_dickens_copperfield.mp301, 01_dickens_copperfield.mp302, 01_dickens_copperfield.mp303, and so on. Next, doing

for file in *.*; do mv "$file" "$file".mp3; done

gives: 01_dickens-copperfield.mp301.mp3, 01_dickens_copperfield.mp302.mp3, *.mp3ac.mp3 and so on.

How do I tell it to split the file into files having the original name but not the extension. Let mv add extention. Sorry for such lenghty expose. I am learning my way into this beautiful jungle but full of powerful animals such as these split, mv.


3 Answers 3


I am assuming you use Linux and GNU split. If so, you can do this directly with split.

So, how does split work? As with most *nix software, its manual is available by running man split. Specifically, the general usage is

split [OPTION]... [INPUT [PREFIX]]

That means that you can specify the prefix yourself. For example, if you split a file called foo and give the prefix bar:

$ ls
$ split foo bar
$ ls
baraa  barab  barac  foo

As you can see, since a prefix was given to split, it has created the files called bar followed by a suffix (aa to ac in this case). So, in your case, you want to give the name of the file as a prefix:

for f in *mp3; do split "$f" "$f"

But you also want to remove the extension so that splitting foo.mp3 does not result in foo.mp3aa but fooaa. This can be done using bash's string manipulation capabilities by writing ${f%.mp3} instead of simple $f.

Finally, you can use another nifty feature of split to add the extension:

          append an additional SUFFIX to file names.

So, putting it all together:

for f in *mp3; do 
   split --bytes=2500k --additional-suffix=".mp3" -d "$f" "${f%.mp3}_"; 

I ran this in a directory that contained the following files:

aa.mp3  bb.mp3  cc.mp3

And it resulted in these split file names:

aa_00.mp3  aa_02.mp3  bb_00.mp3  bb_02.mp3  cc_00.mp3  cc_02.mp3
aa_01.mp3  aa_03.mp3  bb_01.mp3  bb_03.mp3  cc_01.mp3  cc_03.mp3
  • that's what I was looking for: the stripping capabilities .... ${f%.mp3}. As @peterph noted I was sadly using the commands in cygwin on windows and there split binary strangely enough didn't support --additional-suffix argument. Tested on linux and it works.
    – towulvr
    Dec 29, 2013 at 7:35

First, your loop seems to be semantically flawed - it certainly doesn't recreate the original file. What it does is renaming the files. While this will usually work (at least to some extent) with some simply structured data (which MP3s actually are), it will become unusable with most other kinds of data (images and often video for example). Naming the resulting files with the same extension is thus highly unrecommendable - it is rather misleading, since the resulting files are not what the extension would suggest. While on UNIX one can always use the file utility to check what the content of a file is, once you start working with the data on Windows (which your split.exe suggests), you'll realize that that it is a bit suboptimal.

To recreate the original, you would need:

> recreated_original.mp3
for f in *0?; do
   cat "$f" >> recreated_original.mp3

or simply use shell wild-card expansion:

cat *0? > recreated_original.mp3

This will of course overwrite recreated_original.mp3, if it already exists.

If, for some reason, you really want to keep the original extension after the chunk number, your loop is a good way to achieve this. If you happen to be using split from GNU Coreutils, you can use its --additional-suffix option:

split --bytes=2300k -d --additional-suffix=.mp3 01_somefile.mp3 01_somefile.mp3.

Note the trailing dot in the PREFIX argument - this ensures that the names will look like this:


You might want to make the chunk numbers longer by using the -a option, so that you can split the files into more smaller parts (while -a 2 - which is the default - is often not enough, value of 3 or 4 is ok in most cases).

In case you needed to work with chunks of different files separately, you can do it for example in nested loop:

for base in *.00; do
    for file in $base*; do
        # your stuff goes here

${base%.??} returns the content of variable base with the trailing dot and two arbitrary characters removed - thus it becomes the base name of the first chunk. Remember to remove the dot if you use your original chunk naming and to adjust the number of characters used for chunk naming.

  • I don't think the OP is trying to recreate the original. They just want each fragment to have the extension .mp3.
    – terdon
    Dec 28, 2013 at 17:19
  • @terdon might be, but it really is not a good idea.
    – peterph
    Dec 28, 2013 at 17:26
  • @peterph yes I am not trying to recreate the original, but what you 've put in your answer obliges me to further inquiry and practice.As terdon already showed in his answer, I am able to split one mp3 into others and they work as mp3 really well(well, its about audiobooks that I find large, the resulting pieces flow one after another quite nicely)
    – towulvr
    Dec 29, 2013 at 7:24

When you do the split, use basename to strip the .MP3 to create the stem you require.

for file in *.MP3; do split.exe --bytes=2500k -d "$file" `basename "$file" .MP3`; done

Now your second loop should do as you want.

  • @terdon: From a basename(1) manpage: 'the suffix string suffix, if present, shall be removed.' The invocation of basename in this answer includes a suffix string.
    – user26112
    Dec 28, 2013 at 21:03
  • @EvanTeitelman ah, I stand corrected, thank you. X Tian, my apologies, clearly I should have checked before commenting. Downvote removed, upvote added.
    – terdon
    Dec 28, 2013 at 23:09
  • @X Tian, the command didn't work it gives a bunch of split: basename "$file" .mp300: invalid argument
    – towulvr
    Dec 29, 2013 at 7:13
  • @innn Hmm, only reason I could imagine is if the back-quotes were omitted, split should not see the word basename. (@terdon I missed your edit and down-vote, but apologies accepted, tks)
    – X Tian
    Dec 29, 2013 at 13:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .