Saguaro
Saguaro

Reputation: 11

Simple BASH script needed: moving and renaming files

Decades ago I was a programmer (IBM assembly, Fortran, COBOL, MS DOS scripting, a bit of Visual Basic.) Thus I'm familiar with the generalities of IF-Then-Else, For loops, etc.

However, I'm now needing to delve into Bash for my current job, and I'm having a difficult time with syntax and appropriate commands for what I need.

I'm in need of a trivial (concept-wise) script, which will:

  1. Determine if a specific folder (e.g., ~/Desktop/Archive Folder) exists on the user Desktop
  2. If not, create it ("Archive")
  3. Move all files/folders on desktop - except for ~/Desktop/Archive, into "Archive Folder" - AND appending a timestamp onto the end of the filenames being moved.

It is this very last piece - the timestamp addition - which is holding me up.

I'm hoping a clear and simple solution can be sent my way. Here is what I've come up with so far:

#!/bin/bash
shopt -s extglob
FOLDERARCH="Archive Folder"
cd ~/Desktop
if [ ! -d $"FOLDERARCH" ]; then
mkdir "$FOLDERARCH"
echo "$FOLDERARCH did not exist, was created"
fi
mv !(-d "$FOLDERARCH") "$FOLDERARCH"

One final note: the script above works (without the timestamp piece) yet also ends with the message

mv: rename Archive Folder to Folder/Archive Folder: Invalid argument

Why?

Any help will be deeply, deeply appreciated. Please assume I know essentially zilch about the BASH environment, cmds and their arguments - this first request for assistance marks my first step into the journey of becoming at least proficient.

Update

First: much gratitude for the replies I've gotten; they've been very useful.

I've now got was it essentially a working version, but with some oddities I do not understand and, after hours of attempted research, have yet to understand/solve.

I'm hoping for some insight; I feel I'm on the verge of making some real headway in comprehending, but these anomalies are hindering my progress. Here's my (working, with "issues") code so far:

shopt -s extglob
FOLDERARCH="Archives"
NEWARCH=$(date +%F_%T)
cd ~/Desktop
if [ ! -d $"FOLDERARCH" ]; then
    mkdir "$FOLDERARCH"
    echo "$FOLDERARCH did not exist, was created"
fi
mkdir "$FOLDERARCH/$NEWARCH"
mv !(-d "$FOLDERARCH") $FOLDERARCH/$NEWARCH

This in fact largely accomplishes my goal, but:

I don't understand this at all; what should be happening is that all files/folders on the desktop EXCEPT the /Desktop/Archives folder should be moved into a newly created "subfolder" of /Desktop/Archives, e.g., /Desktop/Archives/2016-01-10_00:06:54. In fact, the move accomplishes my goal, but that the message arises makes no sense to me. What is the invalid argument?

One last note: at this point in my newbie-status I'm looking for code which is clear and easy to read, versus much more elegant/sophisticated one-line piped-command solutions. I look forward to working my way up to those in due time.

Upvotes: 1

Views: 650

Answers (1)

David C. Rankin
David C. Rankin

Reputation: 84559

You have several options. One of the simplest is to loop over the directories below ~/Desktop and if they are not "$FOLDERARCH", move them to "$FOLDERARCH", e.g.:

for i in */; do
    [ "$i" != "$FOLDERARCH"/ ] && mv "$i" "$FOLDERARCH"
done

I haven't run a test case, but something similar to the following should work.

#!/bin/bash
shopt -s extglob
FOLDERARCH="Archive Folder"
cd ~/Desktop || { printf "failed to change to '~/Destop'\n"; exit 1; }
if [ ! -d "$FOLDERARCH" ]; then
    if mkdir "$FOLDERARCH" , then
        echo "$FOLDERARCH did not exist, was created"
    else
        echo "error: failed to create '$FOLDERARCH'"
        exit 1
    fi
fi

for i in */; do
    [ "$i" != "$FOLDERARCH"/ ] && mv "$i" "$FOLDERARCH"
done

I apologize, I forgot the datestamp portion. As pointed out in the comments, you can include the datestamp (set the format to your taste) with something similar to the following:

tstamp=$(date +%s)
for i in */; do
    [ "$i" != "$FOLDERARCH"/ ] && mv "$i" "$FOLDERARCH/${i}_${tstamp}"
done

Upvotes: 2

Related Questions