7

I have some files with .mkv extension and I want to calculate their total size using du -h. Some of the files are preceded by whitespace characters.

ranveer@ranveer:~$ ls *.mkv
Arrow.S01E02.720p.HDTV.X264-DIMENSION_(1)  [SHYAMPAREEK.IN].mkv
mymediafirefreefreak.com_The.Mentalist.S05E04.480p.HDTV.X264-mRS.mkv
SHYAMPAREEK.IN-The.Vampire.Diaries.S04E02.720p.HDTV.X264-DIMENSION_(1).mkv
Supernatural.S08E03.720p.HDTV.X264-DIMENSION_(1)SHYAMPAREEK.IN].mkv
  [WWW.SHYAMPAREEK.IN].Arrow S01E01 480p HDTV.mkv
 [WWW.SHYAMPAREEK.IN].Castle.2009.S05E03.480p.HDTV.x264-mSD.mkv
ranveer@ranveer:~$ 

Now, I am using xargs to apply du -h to each of the files but for the files which are preceded by whitespace characters I am getting No such file or directory error.

ranveer@ranveer:~$ ls *.mkv | xargs -I f du -h "f" | awk '{print $1}'
du: cannot access `[WWW.SHYAMPAREEK.IN].Arrow S01E01 480p HDTV.mkv': No such file or directory
du: cannot access `[WWW.SHYAMPAREEK.IN].Castle.2009.S05E03.480p.HDTV.x264-mSD.mkv': No such file or directory
186M
151M
185M
186M
ranveer@ranveer:~$ 

But when I apply du -h to those files individually it works fine.

ranveer@ranveer:~$ du -h "  [WWW.SHYAMPAREEK.IN].Arrow S01E01 480p HDTV.mkv"
151M      [WWW.SHYAMPAREEK.IN].Arrow S01E01 480p HDTV.mkv
ranveer@ranveer:~$ 

So, why am I getting error when using the combination of xargs & du -h.

5 Answers 5

5

Using xargs can be confusing sometimes. If you want to use it reliably, you either should make its input be \0-separated, i. e.

ls | tr \\n \\0 | xargs -0 stat

in order to change the newlines to \0s, or do (if you have a recent xargs)

ls | xargs -d \\n stat
2
  • This answer helped me out so much. Thanks
    – Alex Lowe
    Aug 13, 2016 at 2:59
  • 1
    please, why?? why??? find -print0 | xargs -0 stat
    – CervEd
    Aug 6, 2021 at 15:30
3

You don't really need xargs in this case: du -h -- *.mkv | awk '{print $1}'

Anyway, to fix your problem ls *.mkv | xargs du -h | awk '{print $1}'

enter image description here

Works for me, bash4.2

11
  • Thats even better but still curious why it is not working with xargs.
    – RanRag
    Oct 24, 2012 at 10:50
  • 1
    @RanRag because you have heading spaces in your filename, that wasn't a typo right?
    – daisy
    Oct 24, 2012 at 10:53
  • 1
    @RanRag: parsing the output of ls is the problem. You have files with spaces at the beginning apparently, and that's being lost somewhere. Use find -print0 and xargs -0 if you need this sort of thing. (But better not use any of that if you actually don't need it.)
    – Mat
    Oct 24, 2012 at 10:55
  • @RanRag solution posted
    – daisy
    Oct 24, 2012 at 10:55
  • Yes, I know I have leading space that's why I wrapped the xargs f in "".
    – RanRag
    Oct 24, 2012 at 10:56
2

Your command is a bit Rube Goldberg-esque. Take the list of files *.mkv. List those files (potentially replacing some nonprintable characters by an approximate representation). Parse the list (with some parsing rules that don't quite match the way the list is generated). Pass the individual parsed elements to the du command (which would be capable of taking multiple arguments).

The ls command doesn't expand wildcards, it's the shell that does. Do not parse the output of ls, it's practically never needed and often breaks something.

The input format of the xargs command doesn't match what any other command produces. Yes, it's bizarre. With -I, xargs ignores indentation, which is why the file names with initial spaces are mangled. Do not use xargs except with the -0 option or when you know your input doesn't contain characters that would confuse it.

Just write

du -h *.mkv | awk '{print $1}'
0

Try adding \ before your ls, e.g.: \ls | xargs file.

3
  • 5
    Could you explain why that would help in this case?
    – Mat
    Nov 29, 2012 at 13:30
  • 1
    only in cases when ls is aliased to an option with color printing, because xargs don't know about ANSI codes and pass them through the next command
    – phuclv
    Jan 31, 2018 at 6:38
  • This was the correct answer for when searching for an answer to the error message.
    – alexpotato
    Jan 28, 2020 at 18:54
0

I think you need "-0".

https://man7.org/linux/man-pages/man1/xargs.1.html

Because Unix filenames can contain blanks and newlines, this default behaviour is often problematic; filenames containing blanks and/or newlines are incorrectly processed by xargs. In these situations it is better to use the -0 option, which prevents such problems. When using this option you will need to ensure that the program which produces the input for xargs also uses a null character as a separator. If that program is GNU find for example, the -print0 option does this for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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