Make xargs handle filenames that contain spaces

前端 未结 12 1130
北恋
北恋 2020-11-29 15:21
$ ls *mp3 | xargs mplayer  

Playing Lemon.  
File not found: \'Lemon\'  
Playing Tree.mp3.  
File not found: \'Tree.mp3\'  

Exiting... (End of file)  
相关标签:
12条回答
  • 2020-11-29 15:32

    On macOS 10.12.x (Sierra), if you have spaces in file names or subdirectories, you can use the following:

    find . -name '*.swift' -exec echo '"{}"' \; |xargs wc -l
    
    0 讨论(0)
  • 2020-11-29 15:39

    Dick.Guertin's answer [1] suggested that one could escape the spaces in a filename is a valuable alternative to other solutions suggested here (such as using a null character as a separator rather than whitespace). But it could be simpler - you don't really need a unique character. You can just have sed add the escaped spaces directly:

    ls | grep ' ' | sed 's| |\\ |g' | xargs ...
    

    Furthermore, the grep is only necessary if you only want files with spaces in the names. More generically (e.g., when processing a batch of files some of which have spaces, some not), just skip the grep:

    ls | sed 's| |\\ |g' | xargs ...
    

    Then, of course, the filename may have other whitespace than blanks (e.g., a tab):

    ls | sed -r 's|[[:blank:]]|\\\1|g' | xargs ...
    

    That assumes you have a sed that supports -r (extended regex) such as GNU sed or recent versions of bsd sed (e.g., FreeBSD which originally spelled the option "-E" before FreeBSD 8 and supports both -r & -E for compatibility through FreeBSD 11 at least). Otherwise you can use a basic regex character class bracket expression and manually enter the space and tab characters in the [] delimiters.

    [1] This is perhaps more appropriate as a comment or an edit to that answer, but at the moment I do not have enough reputation to comment and can only suggest edits. Since the latter forms above (without the grep) alters the behavior of Dick.Guertin's original answer, a direct edit is perhaps not appropriate anyway.

    0 讨论(0)
  • 2020-11-29 15:41

    Try

    find . -name \*.mp3 -print0 | xargs -0 mplayer
    

    instead of

    ls | grep mp3 
    
    0 讨论(0)
  • 2020-11-29 15:45

    xargs on MacOS doesn't have -d option, so this solution uses -0 instead.

    Get ls to output one file per line, then translate newlines into nulls and tell xargs to use nulls as the delimiter:

    ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer

    0 讨论(0)
  • 2020-11-29 15:48

    The xargs command takes white space characters (tabs, spaces, new lines) as delimiters.

    You can narrow it down only for the new line characters ('\n') with -d option like this:

    ls *.mp3 | xargs -d '\n' mplayer
    

    It works only with GNU xargs.

    For BSD systems, use the -0 option like this:

    ls *.mp3 | xargs -0 mplayer
    

    This method is simpler and works with the GNU xargs as well.

    For MacOS:

    ls *.mp3 | tr \\n \\0 | xargs -0 mplayer
    
    0 讨论(0)
  • 2020-11-29 15:48
    find . -name 'Lemon*.mp3' -print0 | xargs -­0 -i mplayer '{}' 
    

    This helped in my case to delete different files with spaces. It should work too with mplayer. The necessary trick is the quotes. (Tested on Linux Xubuntu 14.04.)

    0 讨论(0)
提交回复
热议问题