I have a file named files.csv, and contains directory name(column A) and file names(Column B)
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