Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Following command prints the path of the song being played.

mpc | head -n 1 
songs/oldSongs/Mukesh_D/041 KANHAIYA = YAAD AAYI ADHI RAAT KO.mp3

Can I delete this file by modifying the command I used to print it?

share|improve this question

4 Answers 4

up vote 4 down vote accepted

To answer your more general question, that's the job of xargs to take a list of words on standard input and convert it to a list of arguments to a command.

However, xargs expects the list as a space, tab and newline separated list of words where single quotes, double quotes and backslash are used to escape those separators (with varying behaviors with regards to nesting of those by different implementations of xargs).

If the input is a newline-terminated list, the canonical way to convert it to the format expected by xargs is to escape every character (though only, backslash, single quote, double quote, underscore (potentially), space and tab are necessary) but newline with a backslash character, which we can do with sed.

mpc | head -n 1 | sed 's/./\\&/g' | xargs rm --

Note that some xargs implementations have a rather low limit on the maximum line length they expect on stdin, so you may want to only escape the necessary characters with those.

With GNU xargs at least, you don't need to do that, you can do:

mpc | head -n 1 | xargs -rd '\n' rm --

(also using the GNU specific -r option to avoid running any command if the input is empty).

share|improve this answer
    
To explain the sed: this converts "input like this" into "\i\n\p\u\t\ \l\i\k\e\ \t\h\i\s". This won't handle newlines, but will properly escape spaces and quotes. Note also that it won't handle the tags problem @ChrisDown describes in his answer. –  dubiousjim Nov 17 '12 at 16:41
    
This answer would be better for an edit that explained why this is necessary and what it accomplishes. –  Caleb Nov 17 '12 at 17:58

You can do this with rm -i "/path/to/music/library/$(mpc -f %file% | head -n 1)". However, be warned that this will break if the filename contains a newline. As the output of mpc -f %file% is relative to your music library path, you need to prepend it to the output.

share|improve this answer
6  
Note that you can work around the second problem using mpc -f %file%. Also, the paths mpc outputs are relative to the music directory you've configured it to search, so you need to add that path in. For example, rm -i "/var/lib/mpd/music/$(mpc -f %file% | head -n 1)" –  Michael Mrozek Nov 17 '12 at 16:43
    
@MichaelMrozek - Great information! Will add it to my post. –  Chris Down Nov 17 '12 at 16:55

Unless you are able to produce NULL-terminated filenames (as e.g. find -print0) you can try to quote the filenames by piping it through sed 's/^/"/;s/$/"/', which adds the quotes at the beginning and end of a line. Note however, that in this case you need to have:

  • one file per line
  • no double quotes in the filenames

The advantage is, that you can pretty much arbitrarily transform the output (e.g. when you decide not to rename rather than to delete or when you need to strip parts of the output).

share|improve this answer

If it's safe to assume you do not have files with double quotes or newlines you can do:

mpc | head -n 1 | sed  's/^/"/g ; s/$/"/g' | xargs rm --

The sed adds quotes around your file name, and xargs turns the input it gets to arguments for the command it is running (in this case, the rm command).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.