0

I need a script for transfering pairs of files into a folder.

I have directory with .pdf files. For every .pdf is a .done (same name, just the pattern is different pdf --> done).

The problem is, there are cases that for a .pdf there is no .done or for a .done there is no .pdf. In this case the script should ignore that specific pair of files and grab the next one.

I want to move all PAIRS of files into the other folder with that script. But no movement for a file which has no pair.

I made a script but I don't know how to make the comparison and the skip in that case:

#!/bin/bash

source directory where all files are

SOURCE_DIR=/var/xms/batch/PDF/

Name of directory you want to move the PDFs to.

DEST_DIR=/var/xms/batch/PDF/put_ready/

Create the destination directory for the moved PDFs, if it doesn't already exist.

[ ! -d $DEST_DIR ] && mkdir -p $DEST_DIR

Search for .done files starting in $SOURCE_DIR

find $SOURCE_DIR -type f -name "*.done" | while read fin do

Try to Find the specific PDF which names the Pattern

fpdf=?????

If a file with .pdf extension exists, move the .done file to the destination dir.

In the event of a file name clash in the destination dir, the incoming file has

a number appended to its name to prevent overwritng of the existing files.

[ -f "$fpdf" ] && mv -v --backup=numbered "$fin" $DEST_DIR/ done

End of script.

2 Answers2

1

Just a few changes to what you had. The main changes are using globbing to find the files and parameter expansion to carve out the parts of the file paths and extensions. Enable the nullglob option so that the value of FOUND_FILE is null if there are no matches. Since you know the done file exists due to the globbing match in the for loop you can check to see if there is a matching pdf. If so, check if either the pdf or the done file already exist in your destination directory. Use an epoch timestamp as a file suffix when there is an existing conflict. It's not perfect because there is still a small possibility that the new file name exists. You could check again if that was a real concern.

#!/bin/bash

source directory where all files are

SOURCE_DIR=/var/xms/batch/PDF

Name of directory you want to move the PDFs to.

DEST_DIR=/var/xms/batch/PDF/put_ready

Create the destination directory for the moved PDFs, if it doesn't already exist.

[ ! -d "$DEST_DIR" ] && mkdir -p "$DEST_DIR"

Enable nullglob in the event of no matches

shopt -s nullglob

Search for .done files starting in $SOURCE_DIR

for FOUND_FILE in "$SOURCE_DIR"/*.done do

Get root file path without extension

FILE_ROOT="${FOUND_FILE%%.*}"

Is there a .pdf to go with the .done file

if [ -f "${FILE_ROOT}.pdf" ] then # Do either of these files exist in the DEST_DIR if [ -f "$DEST_DIR/${FILE_ROOT##*/}.pdf" ] || [ -f "$DEST_DIR/${FILE_ROOT##*/}.done" ] then # Use epoch stamp as unique suffix FILE_SFX="$(date +%s)"

      ## You could still have a file conflict is the DEST_DIR and
      ## maybe you consider checking first or modifying the move command

      # Move the file pairs and add the new suffix
      mv "${FILE_ROOT}.done" "$DEST_DIR/${FILE_ROOT##*/}_${FILE_SFX}.done"
      mv "${FILE_ROOT}.pdf"  "$DEST_DIR/${FILE_ROOT##*/}_${FILE_SFX}.pdf"
  else
      # Move the file pairs
      mv "${FILE_ROOT}.done" "$DEST_DIR/${FILE_ROOT##*/}.done"
      mv "${FILE_ROOT}.pdf"  "$DEST_DIR/${FILE_ROOT##*/}.pdf"
  fi

fi done

End of script.

0

Try this:

for FILE in $(ls $SOURCE_DIR/*.done); do NAME=${FILE::-4}; mv ${NAME}pdf $DEST_DIR 2>/dev/null && mv $FILE $DEST_DIR; done
  • 3
    Welcome to the site, and thank you for your contribution. Please note, however, that parsing the output of ls is highly disrecommended as it will stumble upon "special" characters in the filenames (even as common as a space). Also, note that the "backtick"-style for command-substitutions is deprecated, and the $( ... ) style is now recommended. In addition, it is advisable to quote shell variables. – AdminBee Jul 29 '20 at 15:20
  • Thanks, I've edited the backticks. – Farhad Kia Aug 05 '20 at 08:49