0

I have a .txt file that has a list of folders:

old_folder_path1,new_folder_path1
old_folder_path2,new_folder_path2
old_folder_path3,new_folder_path3

I would like to run a shell command that moves the files from within the old folder to the new folder for each series of folders. Also does not overwrite and does not move subfolders, just the files in each folder.

I can change the syntax of the .txt file as necessary to accommodate this.

1
  • note that comma is a valid character in a filename, so anything using this could break if either or both of old and new directory names contain a comma. Actually, it's easy enough to deal with the new dir having a comma (just limit the field split to the first comma only), but not if the old dir has one...and not if you can't tell which one is supposed to have an embedded comma. Probably safest just to report an error if there are > 1 commas in the input and continue to the next line. Commented Sep 28, 2019 at 2:51

1 Answer 1

0

Using rsync:

while IFS=, read -r src dest; do
    [ ! -d "$src" ] && echo "skipping missing directory \"$src\"" >&2 && continue
    mkdir -p "$dest" && rsync -av --exclude='*/' --remove-source-files --ignore-existing "$src/" "$dest"
done < file.txt

This script reads file.txt line by line and assigns source and target directory to variables src and dest. The line is split on the comma defined in the IFS (internal field separator) variable. If src is not a directory, the while-loop continues with the next line, otherwise the destination directory and its parent directories are created if it doesn't exist.

In the rsync call the following options are used (see man rsync):

  • -a archive mode (shorthand for options -rlptgoD)
  • -v verbose mode
  • --exclude='*/' exclude directories, only non-directories are transferred
  • --remove-source-files remove files from the sending side when transfer is complete (like mv)
  • --ignore-existing don't transfer files that already exist on the destination side

You could save the script as a shell script mv_rsync.sh:

#!/bin/sh

[ $# -ne 1 ] && echo "invalid file argument" >&2 && exit 1
while IFS=, read -r src dest; do
    [ ! -d "$src" ] && echo "skipping missing directory \"$src\"" >&2 && continue
    mkdir -p "$dest" && rsync -av --exclude='*/' --remove-source-files --ignore-existing "$src/" "$dest"
done < "$1"

Make it executable with

chmod +x ./mv_rsync.sh

and run it as

./mv_rsync.sh file.txt
3
  • or instead of rsync, use find. e.g. something like find "$src/" -maxdepth 1 -type f -exec mv -n -t "$dst/" {} + Commented Sep 28, 2019 at 2:44
  • @freddy Thanks, but I get the following errors: run.sh: line 2:$'/r':c command not found Commented Oct 1, 2019 at 20:34
  • @user374369 It seems you have edited the file in Windows. Run dos2unix run.sh to convert the Windows line endings (CR LF) to Unix (LF) style and try again (and maybe do the same on file.txt). Commented Oct 1, 2019 at 20:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.