-2

I have to copy from the current directory to a destination folder all the .txt files that contain a string given as parameter.

To find and display these files I used the code:

mkdir $1

for i in '*.txt'
do
    grep -r -l $2 > lines.log
done

But how can I copy these files?

agc
  • 7,973
  • 2
  • 29
  • 50
  • Please read the descriptions of tags before applying them. "shellscript" is not a programming language, you need to know which shell. – Ulrich Eckhardt Jan 07 '18 at 13:03
  • Why are you iterating over a single string? – melpomene Jan 07 '18 at 14:00
  • Andrei, though the code you posted is syntactically correct, there are a number of reasons why it won't do what you want. I recommend you try *running* it, then look at your results, and try and figure out an error based on the results you see. Then repeat until you have no errors. Your first hint is melpomene's comment. A second hint might be that you're setting `$i` but not using it. Put your code into shellcheck.net for more hints. – ghoti Jan 07 '18 at 14:12
  • Possible duplicate of [grep file for string and copy directory to another directory](https://stackoverflow.com/questions/38230037/grep-file-for-string-and-copy-directory-to-another-directory) – agc Jan 07 '18 at 14:42

1 Answers1

0

Observations:

  • The code seems to imply the destination directory $1 does not exist. Not good, since it might exist.
  • No loop needed.
  • No redirections like > lines.log needed.
  • The grep recursive (-r) option isn't needed, and might cause trouble.

Code:

  1. Simple, but only works for alphanumeric filenames:

    test -e "$1" || mkdir "$1"
    test -d "$1" && cp $(grep -l -s "$2" *.txt) "$1"
    

    Note those tests. If there's no such file, (test -e), create the destination. Then, only if the destination is a directory, copy the files.

    If $1 already exists, but it's not a directory, do nothing.

  2. Robust, (should work with all filenames), but more obscure:

    grep -Zsl "$2" | cpio -p0dmv ../"$1" 
    

    Code stolen from Adam Katz's answer to "grep file for string and copy directory to another directory".

agc
  • 7,973
  • 2
  • 29
  • 50
  • `mkdir -p` will eliminate the need for your first test and do nothing if the target exists, though it will create missing intermediate directories too if it can. Also, `test -e` tests for *existence*, which might be a file or fifo rather than a directory. Also, what happens if a filename starts with a hyphen or contains a space? – ghoti Jan 07 '18 at 14:14
  • @ghoti, True, `mkdir -p` *is* better; but in this instance it's useful for the student to be introduced to the `test` command as a general util. On files starting with hyphens, this code would likely fail -- it also won't work if the filenames contain spaces. We could fix these, but it's also good for students to bump their heads a little. – agc Jan 07 '18 at 14:25