Tuesday, November 12, 2013

Command line calculator

The basic idea of the following command line calculator is
to perform simple arithmetic operations like

$> c 4 * 5

In this example there are empty spaces around the asterix '*',
which the bash will usually expand to the files in your current directory and
break the calculation.
In the following a variant is present in order to prevent the expansion of the bash:

1. in ~/.alias write
alias c='set -f; call_clc'

2. in ~/.bashrc write
funciton call_clc { clc "$*"; set +f; }

3. create the file ~/bin/clc and write there
echo "$*" | tr -d [:blank:] | bc -l

If the directory "~/bin" does not exist, then create it with "mkdir ~/bin".
Finally, add "export PATH~/bin:$PATH" into your ~/.bashrc and execute "chmod u+x ~/bin/clc".
Then just source your .bashrc like ". .bashrc" and your are ready to go.

Now here are other variants, which you could put into your "clc" file.

# /dev/tty is the userers current shell
echo "$*" | tr -d [:blank:] >&1 | tee /dev/tty | bc

Or another variant with named pipes.

mkfifo pipe
echo "$*" | sed -e 's/ //g' | tee pipe &
pid_pipe=$!
bc < pipe
wait $pid_pipe
rm pipe

Wednesday, November 6, 2013

Reading loops

Another example with loops, which read data.
Paste the following sample data into the input.txt file on CompileOnline and run the loops.

Used resources:
ABSG


Aang
Korra
Wang
Eska
Tonraq
Kya
Desna
Senna
Bumi
Raava
Unalaq
Varrik
Vaatu

Filename=input.txt


echo "#  for loop redirection with \"<\""
count=0
name=
for k in $(wc -l $Filename | cut -d' ' -f1 | xargs seq)
do
  read name
  echo "=> $name"
  let "count += 1"
  if [ "${name//$'\r'/$''}" == "Bumi" ]; then
    break
  fi
done < "$Filename"
echo "Lines: $count"


echo "#  while loop redirection with pipe"
count=0
name=
cat "$Filename" | while read name
do
  echo "=> $name"
  ((i++))
  if [ "${name//$'\r'/$''}" == "Bumi" ]; then
    break
  fi
done
echo "Lines: $count"


echo "#  while loop redirection with subshell"
count=0
name=
while read name
do
  echo "=> $name"
  let "count += 1"
  if [ "${name//$'\r'/$''}" == "Bumi" ]; then
    break
  fi
done < <(cat "$Filename")
echo "Lines: $count"


echo "#  while loop redirection with \"<\""
count=0
name=
while [ "${name//$'\r'/$''}" != "Bumi" ]  
do
  read name                 
  echo "=> $name"
  let "count += 1"
done < "$Filename"           
echo "Lines: $count"


echo "#  until loop redirection with \"<\""
count=0
name=
until [ "${name//$'\r'/$''}" == "Bumi" ]
do
  read name
  echo "=> $name"
  let "count += 1"
done < "$Filename"
echo "Lines: $count"

echo "#  while loop redirection with exec"
count=0
name=
exec 3<&0                 
exec 0<"$Filename"        
while [ "${name//$'\r'/$''}" != "Bumi" ]
do
  read name               
  echo "=> $name"
  let "count += 1"
done                      
exec 0<&3                 
exec 3<&-                 
echo "Lines: $count"

Tuesday, November 5, 2013

Simple loops

Here is a small collection of loops you can perform in the bash shell.
Use CompileOnline (ideone works as well)to run the code.

Used resources:
SyntaxHighlighter
Integrate SyntaxHighlighter into blogger
ABSG
CompileOnline


echo
echo "Loop with (()) syntax"
for ((i=1; i<=10; i++))
do
 echo -n "$i; "
 (( i++ ))   
done


echo
echo "Loop with brace expantion"
for i in {a..h}
do
 echo -n "$i; ";
done


echo
echo "Loop with seq"
for i in $(seq 10 -1 0); do
echo -n "$i; "
done


echo
echo "Loop with set positional parameters"
list=$(echo {z..p})
set -- $list
for i; do
echo -n "$i; "
done


echo
echo "Loop within a variable" 
list="alpha beta gamma delta"
for i in $list; do
echo -n "$i; "; 
done


echo
echo "Loop in a variable"
varloop=$(
for i in {1..10}; do
echo -n "$i; "
done
)
echo "$varloop"