I want to run mplayer
on all files in a folder, sorted by size.
I tried the following commands
ls -1S folder | mplayer
ls -1S folder | xargs mplayer
ls -1S folder | xargs -print0 mplayer
but none of these are working.
How to do it right?
I want to run mplayer
on all files in a folder, sorted by size.
I tried the following commands
ls -1S folder | mplayer
ls -1S folder | xargs mplayer
ls -1S folder | xargs -print0 mplayer
but none of these are working.
How to do it right?
Instead, use e.g. for
to loop over the files and call stat
to get the file sizes. To avoid issues with spaces or newlines in filenames, use zero-terminated strings to sort etc.:
for file in folder/*; do
printf "%s %s\0" "$(stat -c %s "$file")" "$file"
done \
| sort -z -k1 -t ' ' \
| cut -z -f2- -d ' ' \
| xargs -0 mplayer
To call mplayer
individually for each file (rather than only once, passing all files as arguments), you’ll need to use a while
loop, and pipe in the above. Unfortunate |
doesn’t work with while
(at least I don’t know how), you need to use process substitution instead:
while IFS= read -r -d '' file; do
mplayer "$file"
done < <(
for file in folder/*; do
printf "%s %s\0" "$(stat -c %s "$file")" "$file"
done \
| sort -z -k1 -t ' ' \
| cut -z -f2- -d ' '
)
Note that the above is Bash code, and uses GNU extensions, it works on Linux but it won’t work without changes e.g. on macOS (BSD cut
has no -z
flag, and stat -c %s
needs to be changed to stat -f %z
).
I created a python script to build an executable file for just that I want to do. Here is the complete python code:
import os
import re
import sys
import glob
dir_name = sys.argv[1]
# Get a list of files (file paths) in the given directory
list_of_files = filter( os.path.isfile,
glob.glob(dir_name + '/*') )
# Sort list of files in directory by size
list_of_files = sorted( list_of_files,
key = lambda x: os.stat(x).st_size)
# Iterate over sorted list of files in directory and
# print them one by one along with size
for elem in list_of_files[::-1]:
file_size = os.stat(elem).st_size
print(f"mplayer {re.escape(elem)}")
You redirect the output to a file and execute this. And voila - mplayer
plays the files in the order from big to small.