{"id":681,"date":"2015-10-20T17:42:48","date_gmt":"2015-10-20T21:42:48","guid":{"rendered":"https:\/\/www.devolve.net\/blog\/?p=681"},"modified":"2018-07-13T11:36:29","modified_gmt":"2018-07-13T15:36:29","slug":"gnu-xargs-is-missing-the-j-option-why","status":"publish","type":"post","link":"https:\/\/www.devolve.local\/gnu-xargs-is-missing-the-j-option-why\/","title":{"rendered":"GNU xargs is missing the -J option. WHY!?!"},"content":{"rendered":"

I find that using an idiom like <\/p>\n

find foo -maxdepth 1 -print0 | xargs -0 -J % mv % bar\/<\/pre>\n

is so useful. It replaces the replstr<\/code> (“%” in this example) with all the arguments at once, or as many as can fit without going over the system’s limit. I couldn’t believe it when I learned that the GNU version of xargs lacks this flag. Yes, it’s only on the BSD xargs<\/a> as far as I can tell.<\/p>\n

Every time I’ve searched, someone suggests using the -I<\/code> flag on GNU xargs instead, but they are not quite the same. The -I<\/code> flag substitutes the replstr<\/code> one argument at a time, so that in the earlier example, instead of executing <\/p>\n

mv foo\/1 foo\/2 foo\/3 bar\/<\/pre>\n

only once, with the -I<\/code> flag it will instead do <\/p>\n

mv foo\/1 bar\/\r\nmv foo\/2 bar\/\r\nmv foo\/3 bar\/<\/pre>\n

I’ve also tried using the -n<\/code> and -L<\/code> flags, but they are mutually exclusive with each other and with -I<\/code>. OK, so we need some kind of klugey workaround.<\/p>\n

find foo -type f -print0 | cat - < (echo bar\/) | xargs -0 -p mv<\/pre>\n

This adds the \"bar\/\" suffix to the standard input before adding it to the end of the mv<\/code> command. \"But,\" you say, \"those strings are supposed to be null-terminated!\" True, but we're providing a suffix rather than an extra replacement argument, so the EOF signaled from the input stream is really all we need.<\/p>\n

There's another, more intuitive way, but harder to get right; get the argument list output from a subshell command:<\/p>\n

mv $(find foo -type f) bar\/<\/pre>\n

But this suffers from not handling weird file names the right way. Instead one could do: <\/p>\n

echo mv $(\/bin\/ls --quoting-style=escape foo) bar\/<\/pre>\n

This actually works better for file names, but lacks the flexibility of find<\/code>.<\/p>\n

Is this stuff really what we ought to do? Just give us the -J, GNU. If you know a different way to deal with this, tweet me @realgeek and I’ll update this post.<\/p>\n","protected":false},"excerpt":{"rendered":"

I find that using an idiom like find foo -maxdepth 1 -print0 | xargs -0 -J % mv % bar\/ is so useful. It replaces the replstr (“%” in this example) with all the arguments at once, or as many as can fit without going over the system’s limit. I couldn’t believe it when I […]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[42,34,41,16,23],"_links":{"self":[{"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/posts\/681"}],"collection":[{"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/comments?post=681"}],"version-history":[{"count":3,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/posts\/681\/revisions"}],"predecessor-version":[{"id":684,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/posts\/681\/revisions\/684"}],"wp:attachment":[{"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/media?parent=681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/categories?post=681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devolve.local\/wp-json\/wp\/v2\/tags?post=681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}