grepcpmobaxterm

mobaXterm copy after grep


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.


Solution

  • 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/