0

I have many files in a SRC folder. I would like to move all the files that follow a particular pattern from this SRC folder to another DST folder along with rename the file with a required extension.

Sample Parameters

SRC directory /Vinodh

Files in /Vinodh folder are TEST01, TEST02, TEST03, TEST04

TEST02 & TEST03 contain the word WORLD

DST directory /TEST

I want to move the TEST02 & TEST03 files to /TEST folder as TEST02.txt and TEST03.txt

I will be typing the command as

cd /Vinodh
grep -l 'WORLD' *TEST*
mv TEST02 /TEST
mv TEST03 /TEST
cd /TEST
mv TEST02 TEST02.txt
mv TEST03 TEST03.txt

I'd like to combine all this to a single line statement or have batch file that copies all the files in a single shot.

ilkkachu
  • 138,973

5 Answers5

1

With GNU tools:

grep -D skip -d skip -lZ WORD /Vinodh/*TEST* | xargs -r0 mv -vt /TEST

Note that if some of those files are symlinks, moving them could break links.

GNU grep can skip devices/fifos with -D skip, and directories with -d skip, but there's no option to skip symlinks. You'd need a shell where globs can specify file types like zsh:

grep -lZ WORD /Vinodh/*TEST*(.) | xargs -r0 mv -vt /TEST

Would only look in regular files.

An alternative is to use find:

LC_ALL=C find /Vinodh/. ! -name . -prune \
  ! -name '.*' -type f -name '*TEST*' -exec grep -lZ WORD {} + |
  xargs -r0 mv -t /TEST

And the POSIX variant if you don't have GNU tools:

LC_ALL=C find /Vinodh/. ! -name . -prune \
  ! -name '.*' -type f -name '*TEST*' -exec grep -q {} \; \
  -exec mv {} /TEST/ \;
0

Loop over the files with for f..., then wrap the mv inside a conditional (see e.g. TestsAndConditionals on BashGuide):

cd /Vinodh
for f in *TEST* ; do
    if grep -q WORLD "$f" ; then
        mv "$f" "/TEST/$f.txt"
    fi
done
ilkkachu
  • 138,973
0

Assuming your shell is Bash:

source_directory='/Vinodh'
destination_directory='/TEST'
for file in "$source_directory/"*; do
  renamed_file="$(basename "$file")"
  if grep -q 'WORLD' "$file"; then
    echo "Moving \"$file\" to \"$destination_directory/${renamed_file%.*}.txt\""
    mv "$file" "$destination_directory/${renamed_file%.*}.txt"
  fi
done
  1. Iterate over all files in $source_directory.
  2. Extract the file name (the part after the last /).
  3. Look for the string WORLD in the file; grep -q is quiet, that is, it just sets the exit code and does not print what it did.
  4. If the string is found in the file, then move it to $destination_directory replacing any suffix with .txt.
ilkkachu
  • 138,973
AlexP
  • 10,455
0

Here's one liner for you:

cd /Vinodh && for x in $(grep -sl 'WORLD' *TEST*); do mv "$x" "/TEST/$x.txt"; done
NarūnasK
  • 2,345
  • 5
  • 25
  • 37
0
grep -li "world" /Vinodh/* | awk '{print "mv" " " $1 " " "/TEST/"}' | sh
grg
  • 197