2

Suppose the application can only open files via command line arguments, how would i go about randomizing a list of file names/paths to accomplish this?

I thought this should be fairly easy but apparently spaces make it more complicated than it should be.


An example:

a.mp3
b.mp3
with space.mp3

When i try $(ls | shuf) the space is not escaped yielding something like with space.mp3 b.mp3 a.mp3.

Using the quote option -Q does not help either because the command substitution escapes the quotes resulting in the following: \"with space.mp3\" \"a.mp3\" \"b.mp3\"

Similarly the escapes of -b get escaped as well: with\\ space.mp3 a.mp3 b.mp3

Something like find's -exec <application> {} \+ without the finding would be perfect...

3 Answers 3

5

Here is a zsh-only variant, getting rid of ls as well as shuf:

mplayer *.mp3(oe:REPLY=\$RANDOM:)

The Glob Qualifier o executes (e) the code between both colons (:). The code in turn assigns every file a pseudo-random number $RANDOM, resulting in an arbitrary order.

To obscure the command a little more, but mainly to save key strokes, you can define a shell function s:

s() { REPLY=$RANDOM }
mplayer *.mp3(oe:s:)

Or, even better, define a key binding, e.g. for CTRL+R for the shuffle part:

bindkey -s '^R' '(oe:REPLY=\\$RANDOM:)^M'

Now, type only mplayer *.mp3 followed by CTRL+R, and the (oe:REPLY=\$RANDOM:) part gets appended and the command line immediately executed (^M).

5

You don't need ls at all. Try

mplayer "${(f)$(shuf -e *.mp3)}"

The problem with ls is that it is often aliased to something like ls --color=always and in that case prints invisible characters which are not recognized properly by other programs (shuf in this example).

5
  • I know that i do not need ls, but ls is not the problem in any case, the problem is zsh escaping characters it should not escape. Also i don't get why anyone would be using color=always instead of auto...
    – brunnerh
    Sep 2, 2014 at 2:08
  • Sometimes "always" can be really useful, e.g. when there is a lot of files in directory: cd /usr/bin; ls -l | less.
    – jimmij
    Sep 2, 2014 at 3:07
  • I presume you mean less -R, otherwise the colour chars are encoded. Supposed one could use it for that, i usually execute ls and scroll the terminal itself.
    – brunnerh
    Sep 2, 2014 at 4:22
  • @H.B.: Sorry to say that, but you shouldn't parse the the output of ls... so I would identify indeed the ls as the problem.
    – mpy
    Sep 2, 2014 at 17:10
  • @mpy: Not buying it, ls -b works just fine.
    – brunnerh
    Sep 2, 2014 at 17:24
0

I think i finally figured out a method: ${(f)"$(ls | shuf)"}

Breakdown:

ls | shuf: Shuffle files/dirs as expected.
"$(...)": The quotes maintain the output as it is, including newlines.
${(f)...}: Splits the result of the expansion at newlines yielding an array of the file/dir names.


"${(f)$(ls | shuf)}" works as well, ${(f)$(ls | shuf)}, does not.

You must log in to answer this question.

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