Bash Useful Scripts
iDog
Change File Extensions
#!/bin/bash
if test $# -lt 2 ; then
echo "$0 src_ext dest_ext"
exit
fi
for fname in *.$1 ; do
echo "Moving: " $fname
newname=${fname%%.*}
if test -f $fname ; then
mv $fname $newname.$2
fi
done
Make a script run from anywhere correctly
How to handle paths in a script? If the relative paths are fixed, but the whole project can be deployed anywhere... In this case, we need to get the absolute path of the script and deduce out the paths of other files from it:
cd $(dirname $0)
SCRIPT_DIR=$(pwd)
anotherDir=${SCRIPT_DIR}/../another_dir
cd ${anotherDir}
[NOTE]:
The commands of getting dir and filename from whole path is very useful:
- dirname - get dir, strip filename
- basename - get file name, strip dir and suffix.
Make string comparison robust
Doing it in following way
if test "x${myStr}" = "xexpected_value" ; then
instead of
if test "${myStr}" = "expected_value" ; then
makes it robust. Otherwise, when the $myStr is empty, the script fails.
diff files and make a line-by-line comparison
diff file1 file2 > tmp
grep '^<' tmp > tmp1
grep '^>' tmp > tmp2
paste tmp1 tmp2 | sed "s/ /^M/g" > result
Note that in the sed command, the first is a tab, entered by pressing <ctrl>-<tab>; the second one (^M) is a line break, entered by pressing <ctrl>-<enter>.
get line count of a file
# input: file name
# output: line numbers in variable $lines
getLineCount() {
theFile=$1
if test ! -f $theFile ; then
lines=0
return
fi
lines=`wc -l $theFile | tr -s ' ' | cut -d ' ' -f 2`
}
log for shell
# log
log() {
if test $# != 2 ; then
echo "ERROR: log() takes 2 parameters: ."
exit 1
fi
level=$1
msg=$2
timestamp=`date '+%Y-%m-%d %H:%M:%S'`
echo "$timestamp $1 - $2"
}
process csv file
while IFS=, read var1 var2 dummy1 var3 dummy2 var4 ; do
# process variables retrieved. following is just an example
echo "$var1;$var2;$var3;$var4"
done < the_file.csv
put the output of a command in variable, and preserve line breaks
text="aaa\nbbb\n"
text="$text$(the_command)"
echo -e "$text"
Note that the '-e' switch in echo command is to make the '\n' in $text work; the quotation marks are used to preserve the line breaks in the command output.
show all processes in a friendly way
# basically all processes are supposed to start on a daily basis. when not for some reason, without
# this squeeze treatment, it screws up...
squeeze() {
$str=$1
months=$(echo 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec' | tr ' ' '\n')
for m in $months ; do
str=$(echo $str | sed "s/$m /$m/")
done
echo $str
}
printHeader() {
echo -e "pid\ttime\tprogram"
echo '---------------------------------'
}
LC_ALL=C
export IFS='
'
myps() {
for p in $pout ; do
p=$(squeeze $p)
pid=$(echo $p | cut -d ' ' -f 2)
pt=$(echo $p | cut -d ' ' -f 9)
param=$(echo $p | cut -d ' ' -f 12-)
found=''
for pInfo in $pInfoList ; do
key=$(echo $pInfo | cut -d '|' -f 1)
desc=$(echo $pInfo | cut -d '|' -f 2)
if test "x$(echo $param | grep $key)" != 'x' ; then
found='Y'
break
fi
done
if test "x$found" == 'x' ; then
desc="UNKNOWN($param)
fi
echo -e "$pid\t$pt\t$desc"
done
}
pout=$(ps auxww | grep -v grep | grep the_key_word | tr ' ')
pInfoList=$(cat << END_OF_LIST
keyword1|my desc1
keyword2|my desc2
keyword3|my desc3
END_OF_LIST)
if test "x$pout" == 'x' ; then
echo 'No running process.'
exit 0
fi
printHeader
myps | sort -k 3