0

I need to find three files from a huge directory and copy them to another directory.

This is what I have done:

find $adir -type f \( -name "a1*" -o -name "a2*" -o -name "a3*" \) -mtime -8 | xargs cp -t $bdir

The file a1 is copied to the destination but other files are not copied to the destination. This is my script:

#!/bin/bash
date=$(date)
day=$(date +"%u")
adir=/x/y
bdir=/a/b
 {
      if [ "$day" == "5" ] ; then
         find $adir -type f \( -name "a1*" -o -name "a2*" -o -name "a3*" \) -mtime -8 | xargs cp -t $bdir
       else
           echo "failed"
       fi
    }

I am running this in a script and the cursor does not return to the terminal. Is there any way I can get it to work?

8
  • What makes you thin it's not working? If $adir is the root of a vast directory structure, then it would take some time to look through all files. Also, you are limiting with -mtime -8, are you sure those files are modified within the last 8 hours? The command also does not copy only a1 but any file than starts with a1 (etc.).
    – Kusalananda
    Aug 25 '17 at 12:25
  • When I run it on a command line the find is working fine.When I use it in BASH script just one file ie,a1 is getting copied, a2 and a3 are not getting copied
    – Shruthi
    Aug 25 '17 at 12:27
  • Well, it's "working" insofar that it's not giving you any error messages, right? In that case, insert set -x on the line before the find in the script to see what actually gets executed. It could be that you have an unexpected value in, for example, $adir (this variable should be double-quoted, by the way, as should $bdir be).
    – Kusalananda
    Aug 25 '17 at 12:30
  • Also, if "the cursor is not returning to the terminal" when executing the script, then there could be something else in the script that is wrong.
    – Kusalananda
    Aug 25 '17 at 12:32
  • The problem is just one file "a1" is being copied others are not.
    – Shruthi
    Aug 25 '17 at 12:33
0

Try removing the brackets. This command works for me direcly in terminal and in a bash shell (changed cp to 'file' to check it works..):

 find . -type f -name "a4*" -o -name "d1*" -o -name "f2*" -mtime -8 | xargs file

You can also try a for loop, which might give you some more space (loop) to do thigs. Change the find line with

for a_file in `find $adir -type f \( -name "a1*" -o -name "a2*" -o -name "a3*" \) -mtime -8`
do
   cp -t $a_file $bdir
done

You can play removing the -mtime -8 and change cp -t $a $bdir for echo "The file is: " $a_file for testing...

19
  • This works for me too in terminal but not on script
    – Shruthi
    Aug 25 '17 at 12:47
  • As commented by Kusalananda, put set -x, but after "#!/bin/bash" and try again.
    – ferranm
    Aug 25 '17 at 12:49
  • @Innov Just to be absolutely clear: the set -x will not fix anything, but will allow you to see what commands actually gets executed.
    – Kusalananda
    Aug 25 '17 at 12:54
  • With set -x I see the command works exactly as I want it to but the files seem not to get copied
    – Shruthi
    Aug 25 '17 at 12:56
  • Your script (with "file" instead of "cp") is working for me. Can you change cp for file? Do you see all the output when adding 'set -x' (it is a minus, not a plus). Also, remove the '(' and ')' and try
    – ferranm
    Aug 25 '17 at 12:58
0

As discussed, your script looks syntactically and grammatically correct, so there must be something outside the script itself that causes it to behave in the way that it does.

Having said that, I can give you my own take on the script. This is the way I would have written the equivalent thing:

#!/bin/sh

day=$(date +'%u')
adir='/x/y'
bdir='/a/b'

case "$day" in
    5)  find "$adir" -type f -mtime -8 -name 'a[123]*' -exec cp {} "$bdir"/ ';'
        ;;
    *)  printf 'Error: Unhandled day "%s"\n' "$day" >&2
        exit 1
esac

This just uses the fact that the various names that you'd like to match may be matched by a single filename globbing pattern. It also does not have a dependency on GNU cp and its -t option (got rid of xargs). And since it's not using any "bashisms", it may as well be interpreted by /bin/sh.

The case ... esac is easier to read (and write) than a bunch of if ... then ... elif.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.