You will probably have seen that your shell gives you a message similar to the one below if you try to do it this way literally:
prompt> mv *.new *.old mv: when moving multiple files, last argument must be a directory Try `mv --help' for more information.
This is more like it:
prompt> ls file1.new file2.new file3.new file4.new prompt> for i in $(ls *.new); do NAME=$i; NEWNAME=$(ls $i| cut -d "." -f 1).old; mv $NAME $NEWNAME; done prompt> ls file1.old file2.old file3.old file4.old
We could have put this in a script, of course, in which we would start a new line after every semicolon. If you plan to use this kind of syntax regularly, that might be a wise idea.
Some explanation on the above syntax:
for i in $(ls *.new)
Build a list of files that should be renamed.
Assign the variable NAME to hold the filename.
NEWNAME=$(ls $i| cut -d "." -f 1).old
Assign the variable NEWNAME to hold the new name of the file, which is the first part (before the dot) of the original name, followed by the string '.old'. Mind the dot, we cut it off, so we have to add it again.
mv $NAME $NEWNAME
For each item in the list, move it to its new name.
You could have obtained the same result in a somewhat more elegant way like this:
prompt> for i in $(ls *.new); do NEWNAME=$(ls $i | sed -e 's/new/old'); mv $i $NEWNAME; done
Say we have a set of logfiles named log, log.0, log.1, log.2, etcetera, following a classic log scheme such as you may find in any /var/log directory. The goal is to increase the indexnumbers by one, to make a new logfile without indexnumber and to keep the total amount of logfiles within limits. For testpurposes, we first create a script that includes the creation of a set of fake log files:
#!/bin/bash # This is the preparation for a simple log rotation script. # First, create a set of test files. touch messages touch messages.0 touch messages.1 touch messages.2 # Put the files to be renamed in reverse order in a list. # If you'd just use ls without the -r option, you'd only have one file left # in the end. LIST=$(ls -r messages*) # Now see what we have. for i in $LIST; do echo $i; # List the files TMP=$(ls $i | cut -d"." -f 2) # See which indexnumber we have echo "(TMP = $TMP)" # Print the indexnumber value if [ $TMP = "messages" ]; then # If there is no index, this file NEW=$TMP.0 # should be renamed to index 0 echo mv $i $NEW elif [ $TMP -gt 4 ]; then # If the indexnumber is larger than 4, echo rm $i # remove the file else BASE=$(ls $i | cut -d"." -f 1) NEW=$BASE.$(($TMP+1)) # If the indexnumber is smaller than echo mv $i $NEW # or equals 4, just rename the file fi done
We don't really do anything here, since we only used echo commands to see what the script is doing. In the real version, we use two arguments to the script: the first argument is the base log file name (without the indexnumber), the second argument is the maximum index number value. Here it is:
#!/bin/bash # Simple log rotation script LIST=$(ls -r $1*) COUNT="$2" for i in $LIST; do echo $i; TMP=$(ls $i | cut -d"." -f 2) if [ $TMP = $1 ]; then NEW=$TMP.0 mv $i $NEW elif [ $TMP -gt $COUNT ]; then rm $i else BASE=$(ls $i | cut -d"." -f 1) NEW=$BASE.$(($TMP+1)) mv $i $NEW fi touch $1 done
For testing, use the first script to populate a test directory, and the second for doing the renaming.
The problem is now that other files get renamed if we don't use any arguments to the log rotate script. So let's build in some safety procedures:
#!/bin/bash # Logrotate script with dummy protection. # If the amount of arguments to the script is not 2, then nothing is done. if [ $# -ne 2 ]; then echo "Usage: logrot.sh base_name_to_rotate max_index_value" echo "e.g. logrot.sh messages 4" exit fi LIST=$(ls -r $1*) COUNT="$2" for i in $LIST; do echo $i; TMP=$(ls $i | cut -d"." -f 2) if [ $TMP = $1 ]; then NEW=$TMP.0 mv $i $NEW elif [ $TMP -gt $COUNT ]; then rm $i else BASE=$(ls $i | cut -d"." -f 1) NEW=$BASE.$(($TMP+1)) mv $i $NEW fi touch $1 done
Even with very little knowledge, you don't need to be a hero to be able to sit back and watch. All my .html files needed to be converted to a file with the same base name but ending in .php, and then the PHP footer and header were to be added. Of course, the lines that made up the old HTML layout, such as <head>, <title> and <body> declarations, needed to be removed first.
Removing the HTML header is easy, that is always the same amount of lines at the beginning of the file. Removing the end, however, proves more difficult. The only thing we know is that the last 21 lines must be deleted. But at which line number do we start? I probably should read more man pages, but tac works just as well, preventing me from having to learn yet another combination of arguments and options and expressions.
Rather lazy than tired, here it is:
#!/bin/bash # specific conversionscript for my html files to php LIST=$(ls *.html) for i in $LIST; do NEWNAME=$(ls $i | sed -e 's/html/php/') cat beginfile > $NEWNAME cat $i | sed -e '1,25d' | tac | sed -e '1,21d'| tac >> $NEWNAME cat endfile >> $NEWNAME done
If all goes well, you may add a line to remove the html files. This scheme will of course only work if you wrote decent HTML files.