Updated : Thanks for your answers. As I said, my q was just a translation of my usecase. Let me get into more details of what I want to achieve. In my dev env, we use "ade" as our version control system what I want to do is :
ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | xargs -iF ade unbranch F
Now, every single time I run the unbranch command, a new file/dir gets checked out. so I need to run ade checkin -all after all my unbranch commands. So I needed something like
"pre part till sort" | xargs -iF (ade unbranch + ade checkin -all)
Any way to run 2 commands on the op of pipe ?
Thanks
Original question asked :
I can translate the usecase I have into the following :
I need to get the 1st line of a file. I do
cat file | head -1
Now I want to do this on a list of files. How do I do the following in one unix command ?? Eg :
find . -name "*.log" | ( xargs -iF cat F | head -1 )
Obviously the brackets in the above command do not work.
is there a way to pipe the output of the find command and do 2 commands on it ( cat and head ) ? Tried using ; and && but dint help. I can create a script - but wanted to do this in one command.
Again - this is just a translation of the case I have.
thanks Rohan
First of all, head
accepts more than one file name, so you can simply write:
head -q -n 1 *.log
or:
find . -name '*.log' -exec head -n 1 '{}' ';'
However, if you really need to duplicate the stream, then use tee
and do something along the lines of:
wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) > dvd.iso
This example is taken from info coreutils 'tee invocation'
.
UPDATE (Following the ade
comment) In your case tee
will not work. You need to perform a task after another task finishes, and tee
will trigger the tasks more or less simultaneously (modulo buffering).
Another approach will work, provided that there are no spaces in the input lines (a serious issue, I know, but I'm not sure how to overcome it right now). I'll start with a generic solution:
echo -e 'Foo\nBar\nBaz' | ( for i in `cat` ; do echo 1$i ; echo 2$i ; done )
Here, echo -e 'Foo\nBar\nBaz'
creates a sample multi-line input, echo 1$i
is the first command to run, echo 2$i
is the second command to run.
I'm not familiar with ade
and I don't have it installed on my system, but I'm guessing that in your case something like this might work:
ade describetrans | awk '/myapps/{ print $2 }' | sort -fr | ( for i in `cat` ; do ade unbranch $i ; ade checkin -all $i ; done )
Useless use of cat
. Simply pass the file names to head
:
find . -name '*.log' -exec head -n 1 '{}' '+'
or
find . -name '*.log' -print0 | xargs -0 head -n 1
EDIT: This will print headers for each file. On Linux, this can be suppressed with -q
, but on other systems you must make sure that head
is called with a single argument:
find . -name '*.log' -exec head -n 1 '{}' ';'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With