简体   繁体   中英

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 (eg, ~/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:

  • In the case where the desktop Archives folder already exists, I'm expecting the if-then construct to simply follow through (with no echo msg) to the following mkdir command, but instead the msg "Archives not exist, was created" msg is output anyway (erroneously). Any answers as to why?

  • The script completes with the following msg:

     mv: rename Archives to Archives/2016-01-10_00:06:54/Archives: Invalid argument 

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 , eg, /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.

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" , eg:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM