mobaXterm copy after grep

116 views Asked by At

I am doing

grep -l 0000201290 ServerApplication.log* | xargs cp  j231110_4/

but it tells me

cp: can't stat 'ServerApplication.log.5/j231110_4': Not a directory

Which is correct, it should be 'j231110_4/ServerApplication.log.5', because 'j231110_4' is a directory and 'ServerApplication.log.5' is a file I want to be copied in directory 'j231110_4'.

How can I copy grep output list of files to some dir?

Have tried How to pipe output from grep to cp? but it does not work. I guess mobaXterm works differently than linux.

1

There are 1 answers

4
Paul Hodges On BEST ANSWER

Your arguments are ending up in the wrong order. Use xargs' -I for a placeholder.

grep -l 0000201290 ServerApplication.log* | xargs -I@ cp "@" j231110_4/

This is pretty forgiving as long as your replacement string doesn't show up anywhere else in your command.

$: echo 1 2 3 | xargs -Ibar echo "cp 'bar' foo/"
cp '1 2 3' foo/

$: rm -fr foo/; mkdir -p foo/; touch '1 2 3'; echo 1 2 3 | xargs -Ibar cp 'bar' foo/; ls -l foo/
total 0
-rw-r--r-- 1 P2759474 1049089 0 Nov 13 08:50 '1 2 3'

ah, BusyBox...

I get xargs: unknown option -- I BusyBox v1.22.1 (2015-11-10 11:07:12 ) multi-call binary. . . .

Try this then: use cp's -t option to make the argument order irrelevant.

grep -l 0000201290 ServerApplication.log* | xargs cp -t j231110_4/

It should work as long as you do NOT have any weird characters like embedded spaces in your filenames - looks likely, but I try to make as few assumptions as possible. I ran a quick test on a HackerRank BusyBox v1.36.1, so hopefully v1.22.1 will respect -t.

If you do have odd characters... try this.

mapfile -t lst < <( grep -l 0000201290 ServerApplication.log* )
cp -t j231110_4/ "${lst[@]}"

If none of those work for whatever reason, fall back to simplest:

grep -l 0000201290 ServerApplication.log* |
  while read -r file; do cp "$file" j231110_4/; done

This will still fail on embedded newlines, so check your data.

Or (again, as long as there are no embedded surprises) just

cp $(grep -l 0000201290 ServerApplication.log*) j231110_4/
  • but be aware of why you are using the versions that aren't generally safe. "Convenient" syntax isn't always the best idea.