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
Farhad Kia
  • 78
  • 6
  • 3
    Welcome to the site, and thank you for your contribution. Please note, however, that parsing the output of `ls` is [highly disrecommended](https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead) 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](https://unix.stackexchange.com/questions/126927/have-backticks-i-e-cmd-in-sh-shells-been-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