Home > Enterprise >  Bash script to find files from a directory and move them to different location
Bash script to find files from a directory and move them to different location

Time:03-23

I have a file named files.csv, and contains directory name(column A) and file names(Column B)

enter image description here


Currently the files(file1,file2..) are available in the linux machine in a different directory and would need to move them as per the details provided in files.csv file. I humbly request suggestions on bash script, that can help me first find the files mentioned in the csv file and further move them according to the directory name provided.

CodePudding user response:

As file & directory names could contain almost any character, it is recommended to use a CSV-aware tool for parsing it; but supposing that they don't contain any ,, ", \r or \n then you could do:

#!/bin/bash

from=/home/admin/main
to=/home/admin/Documents

while IFS=',' read -r dirname filename
do
    mkdir -p "$to/$dirname"
    mv "$from/$filename" "$to/$dirname/"
done < <(sed $'s/\r$//' files.csv)

CodePudding user response:

Suggesting a bash script.

The following is a programmatic solution approach. Not tested!!!

Be very careful before executing mv command as it maybe destructive.

#!/bin/bash

#create a find command to locate all files in single command:
findCommand=$(awk -F, '{filesArr[  c]=$2;}END{
  cmd = "find / ";
  seperator = "";
  for (i in filesArr) {
    cmd = sprintf("%s %s -name \"%s\"", cmd, seperator, $2);
    seperator = "-or"
  }
  cmd = cmd " 2>/dev/null";
  print cmd;
}' input.csv)

#print findCommand
echo "$findCommand"

# collect all file names in filesList (can take long time to execute)
# assuming filename are unique and not contain `&` in filenames
readarray -t filesList <<< $("$findCommand")

# for each found file
for file in ${filesList[@]}; do
   #append found file to csv list to match its basename
   currFilename=$(basename "$file")
   sed -i 's|'"$currFilename"'|'"$currFilename","$file"'|' input.csv
done
# if files are located in 2 or more place, the csv will append absolute path to each location,
# if file is not located its 3rd column will stay empty

# build a mv commands for each file with location using awk
awk -F, 'NF>2{cmd=" mv "$3" "$1;print cmd}' input.csv

# when ready to run the mv commands uncomment the following line
# awk -F, 'NF>2{cmd=" mv "$3" "$1;system(cmd)}' input.csv
  • Related