mpen
mpen

Reputation: 283043

How to run a command that only takes 1 arg with multiple args and redirect stdout?

I'm trying to run this command called codemaker which takes a filename as input but then writes the output to stdout instead of back to the file, so I have to redirect stdout to that file. That works fine, but I want to do this for a whole bunch of files at once, so I came up with this (based on https://stackoverflow.com/a/845928/65387):

ctouch() {
  xargs -t -i -0 sh -c 'codemaker "$1" > "$1"' -- {} <<<"${(ps:\0:)@}"
}

But I can't quite get the syntax right. It looks like it's treating everything as a single arg still:

❯ ctouch foo.h bar.cc                                                                                                      
sh -c 'codemaker "$1" > "$1"' -- 'foo.h bar.cc'$'\n'

Whereas I just want to run 2 commands:

codemaker foo.h > foo.h
codemaker bar.cc > bar.cc

How do I make an alias/function for that?

(And no, I'm not sure about that <<<"${(ps:\0:)@}" bit either. Really hard to Google. I want the usual "$@" to expand with null separators to feed to xargs)

Upvotes: 0

Views: 51

Answers (2)

user1934428
user1934428

Reputation: 22291

I don't see a compelling reason to use xargs in your case. You just create additional processes unnecessarily (one for xargs, plus for each argument, one shell process).

A simpler solution (and IMO easier to understand) would be to do it with this zsh-function:

ctouch() {
  for f
  do
    codemaker $f >$f
  done
}

Upvotes: 2

mpen
mpen

Reputation: 283043

I think this is a lot easier to just do with printf.

ctouch() {
  printf -- '%s\0' "$@" | xargs -t -i -0 sh -c 'codemaker "$1" > "$1"' -- {}
}

Upvotes: 1

Related Questions