I'm trying to run the following command:
find . -iname '.#*' -print0 | xargs -0 -L 1 foobar
where "foobar" is an alias or function defined in my .bashrc file (in my case, it's a function that takes one parameter). Apparently xargs doesn't recognize these as things it can run. Is there a clever way to remedy this?
-
I usually use find like this:
find . -iname '' -exec cmd '{}' \;'{}' will get replaced with the filename, and \; is necessary to terminate the execution chain. However, if that doesn't work with your function, you might need to run it through bash:
find .. |sed -e "s/.*/cmd '&'/"|bashFind prints each file on a line, sed just prefixes this with your command, and then pipe it to bash for execution. Skip the |bash first to see what will happen.
ephemient : If you're using a newish GNU find, use `-exec cmd '{}' +` instead: this acts more like xargs in that it will batch arguments together into one run instead of exec'ing a new cmd for every file found.Alnitak : I rather think if his function was capable of taking multiple parameters he wouldn't be supplying the -L 1 options to xargs...ephemient : Oh, that's what -L does? I didn't look it up, and I use -n for that purpose.IanGreenleaf : Sadly, these methods still don't work with aliases and functions. Probably because .bashrc only gets invoked for interactive shells. But the first one IS a neat trick. -
This doesn't work because
xargsexpects to be able toexecthe program given as its parameter.Since
foobarin your case is just abashalias or function there's no program to execute.Although it involves starting
bashfor each file returned byfind, you could write a small shell script thus:#!/bin/bash . $(HOME)/.bashrc func $*and then pass the name of that script as the parameter to
xargs -
Since only your interactive shell knows about aliases, why not just run the alias without forking out through
xargs?find . -iname '.#*' -print0 | while read -d $'\0' i; do foobar "$i"; done$'\0'requiresshopt -s extquote, which is on by default. If you're sure that your filenames don't have newlines in them (ick, why would they?), you can simplify this tofind . -iname '.#*' -print | while read i; do foobar "$i"; doneor even just
find -iname '.#*' | ..., since the default directory is.and the default action is-print.One more alternative:
IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; donetelling Bash that words are only split on newlines (default:
IFS=$' \t\n'). You should be careful with this, though; some scripts don't cope well with a changed$IFS. -
Using Bash you may also specify the number of args being passed to your alias (or function) like so:
alias myFuncOrAlias='echo' # alias defined in your ~/.bashrc, ~/.profile, ... echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0 echo arg1 arg2 | xargs bash -cil 'myFuncOrAlias "$@"' arg0
0 comments:
Post a Comment