0

I have to move some files from one folder to another, criteria set by a find and grep. When I try to move the files it breaks.

The actual move it's trying is mv /somefolder/export//somefolder/storage/testfileOLD.txt

What I expected was mv /somefolder/storage/testfileOLD.txt /somefolder/export/testfileOLD.txt

The command I'm using:

find /somefolder/storage/ -type f -name "*OLD*" -newermt '2019-05-1' ! -newermt '2019-06-7' -exec grep -qiF 'closed' {} \; -exec mv {} /somefolder/export/{} \;

I already tried with -exec basename {}, this gives me the right result, but when I modify the mv to

-exec echo {} /somefolder/export/$(basename {}) \;

to check if it works it still gives me the /somefolder/export//somefolder/storage/testfileOLD.txt.

1
  • Do you need the {} in destination for mv? It should work fine if you just leave it as -exec mv {} /somefolder/export/ \;
    – deimos
    Jun 5, 2019 at 14:19

2 Answers 2

0

$(basename {}) will fail (better: just be an empty string). The subshell invoked here does not expand {} to the filename as this is specific to find and not exported into the subshell your command creates.

You can test this by running

find -exec echo "this will be empty:" $(basename '{}') \;

I suggest you write a small script:

#!/bin/bash
mv "$1" /somefolder/export/"$( basename ${1})"

and run it in your find command:

find /dir/ <specs> -exec grep -qiF 'closed' '{}' \; -exec bash script.sh '{}' \;

AFAIK the behaviour of forwarding '{}' to subshells depends on your find-version.

2
  • Updated - I had focused on how to circumvent '{}' for more complex commands in find
    – FelixJN
    Jun 5, 2019 at 14:00
  • 1
    thanks, I used your idea, but used the inline sh -c for this to work -exec sh -c 'mv {} /somefolder/export/$(basename "$1")' sh {} as this will not add extra scripts on the server (even one that can be deleted directly afterwards)
    – Joris D R.
    Jun 5, 2019 at 14:18
0

If you want to retain the original structure below directory /somefolder/somedir, you could use rsync instead of mv.

Test setup:

/somefolder/storage/testfileOLD.txt
/somefolder/storage/subdir/fileOLD.txt

Expected result after move:

/somefolder/export/testfileOLD.txt
/somefolder/export/subdir/fileOLD.txt

The commands:

# first, create a file list of relative paths (some arguments removed for simplicity)
$ find /somefolder/storage -type f -name "*OLD*" -printf '%P\n' > /tmp/filelist

# cat to illustrate its content
$ cat /tmp/filelist
subdir/fileOLD.txt
testfileOLD.txt

# then rsync using `--remove-source-files` to move the files 
$ rsync -av --remove-source-files --files-from=/tmp/filelist /somefolder/storage /somefolder/export

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .