Bash – Is it possible to split file and append the pieces with same extension in one liner

bashrenamesplit

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

Doing

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.

Best Answer

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
foo
$ 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:

   --additional-suffix=SUFFIX
          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}_"; 
done

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
Related Question