Showing posts with label Shell Script. Show all posts
Showing posts with label Shell Script. Show all posts

Saturday, 25 March 2017

迭代文件中的行、单词和字符


1. 迭代文件中的每一行

  • while 循环法
while read line;
do
echo $line;
done < file.txt

改成子shell:
cat file.txt | (while read line;do echo $line;done)
  • awk法:
cat file.txt| awk '{print}'

2.迭代一行中的每一个单词

for word in $line;
do 
echo $word;
done

3. 迭代每一个字符

${string:start_pos:num_of_chars}:从字符串中提取一个字符;(bash文本切片)
${#word}:返回变量word的长度

for((i=0;i<${#word};i++))
do
echo ${word:i:1);
done

[URL=http://www.visitormap.org/][IMG]http://www.visitormap.org/map/m:bekbxjyftgtbwlff/s:1/c:ffffff/p:dot/y:0.png[/IMG][/URL]

Tuesday, 21 March 2017

awk 数据流处理工具 (a)


  • awk脚本结构
awk ' BEGIN{ statements } statements2 END{ statements } '

  • 工作方式
1.执行begin中语句块;
2.从文件或stdin中读入一行,然后执行statements2,重复这个过程,直到文件全部被读取完毕;
3.执行end语句块;

print 打印当前行

  • 使用不带参数的print时,会打印当前行;

  echo -e "line1\nline2" | awk 'BEGIN{print "start"} {print } END{ print "End" }' 

  • print 以逗号分割时,参数以空格定界;

echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
print var1, var2 , var3; }'
$>v1 V2 v3

  • 使用-拼接符的方式(""作为拼接符);

echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
print var1"-"var2"-"var3; }'
$>v1-V2-v3

特殊变量: NR NF $0 $1 $2

NR:表示记录数量,在执行过程中对应当前行号;
NF:表示字段数量,在执行过程总对应当前行的字段数;
$0:这个变量包含执行过程中当前行的文本内容; 当前行的所有内容。
$1:第一个字段的文本内容; 即第一列的内容。
$2:第二个字段的文本内容;即第二列的内容。
$3:第三个字段的文本内容;即第三列的内容。
... $n:  第n个字段的文本内容;即第n列的内容。

echo -e "line1 f2 f3\n line2 \n line 3" | awk '{print NR":"$0"-"$1"-"$2}'

  • 打印每一行的第二和第三个字段:
  awk '{print $2, $3}' file

  • 统计文件的行数:
  awk ' END {print NR}' file

  • 累加每一行的第一个字段:
  echo -e "1\n 2\n 3\n 4\n" | awk 'BEGIN{num = 0 ;
  print "begin";} {sum += $1;} END {print "=="; print sum }'

传递外部变量

var=1000
echo | awk '{print vara}' vara=$var #  输入来自stdin
awk '{print vara}' vara=$var file # 输入来自文件

Monday, 20 March 2017

summarizeSpecTimes.sh

Borrowed from Nemanja, need to learn.


#!/usr/bin/env bash

if [[ -z "$3" ]]     # here  -z means: True if string is empty. from 'help test' doc
then
  echo "Usage: $0 -o <DIR> Baseline:<SPEC.out.csv> [<NAME>:<SPEC.out.csv> ...]"
  echo
  echo "This script creates a csv file that contains a summary of multiple SPEC"
  echo "run result csv files. The baseline is assumed to be the very first file"
  echo "passed in."
  echo "The -o option is mandatory and must appear prior to the list of files."
  echo
  echo "Sample invocation:"
  echo "$0 -o Summaries Baseline:CINT2006.110.ref.csv \\"
  echo "  Baseline:CFP2006.110.ref.csv NoCRBits:CINT2006.112.ref.csv \\"
  echo "  NoCRBits:CFP2006.112.ref.csv CheapBR:CINT2006.111.ref.csv \\"
  echo "  CheapBR:CFP2006.111.ref.csv"
  echo
  echo "Implementation detail: For processing the inputs, the script will"
  echo "create a directory for each of the named runs which it will clean"
  echo "up after. If this directory happens to contain directories of the"
  echo "same name, the script will prompt you before overwriting them."
  exit 1
fi

###########################SCRIPT BEGINS ON LINE 78#############################

function summarizeBench {
  SUMMARY=""
  if [ $(cat CurrBenchRunTimes.txt | wc -l) -eq 1 ]
  then
    cat CurrBenchRunTimes.txt CurrBenchRunTimes.txt > tmpCurrBenchRunTimes.txt
    mv tmpCurrBenchRunTimes.txt CurrBenchRunTimes.txt
  fi
  while read RT
  do
    SUMMARY="$SUMMARY $RT"
  done < CurrBenchRunTimes.txt
  echo $1,$($SUMMARIZE -a $SUMMARY)
}

function summarizeIndividualFile {
  START=0
  PREV_BENCH=""
  while IFS=, read BENCH REF_T RUN_T RATIO REST
  do
    if [ "$BENCH" = Benchmark ]
    then
      START=1
      continue
    fi
    if [ $START -ne 1 ]
    then
      continue
    fi
    if echo $REST | grep ',NR,' > /dev/null
    then
      continue
    fi
    if [[ -z "$BENCH" ]]
    then
      summarizeBench $PREV_BENCH
      break
    fi
    if [ "$BENCH" = "$PREV_BENCH" ]
    then
      echo $RUN_T >> CurrBenchRunTimes.txt
    else
      if [[ -n "$PREV_BENCH" ]]
      then
        summarizeBench $PREV_BENCH
      fi
      PREV_BENCH=$BENCH
      echo $RUN_T > CurrBenchRunTimes.txt
    fi
  done < $FILE_TO_READ
}

function addNamedSummary {
  echo "$(head -1 $OUTDIR/FinalSPECSummary.csv),$1(Median),$1(Best),$1(Worst),$1(%Variance),$1(%Diff(Median)),$1(%Diff(Best)),$1(%Diff(Worst))" > tmpSPECSummarizer.txt
  cat $1/* | while IFS=, read BENCH MEDIAN BEST WORST VARIANCE
    do
      BASE_LINE=$(grep ^$BENCH $OUTDIR/FinalSPECSummary.csv)
      BASE_MEDIAN=$(echo $BASE_LINE | cut -f2 -d,)
      BASE_BEST=$(echo $BASE_LINE | cut -f3 -d,)
      BASE_WORST=$(echo $BASE_LINE | cut -f4 -d,)

      DIFF_MEDIAN=$($SUMMARIZE -d $BASE_MEDIAN $MEDIAN)
      DIFF_BEST=$($SUMMARIZE -d $BASE_BEST $BEST)
      DIFF_WORST=$($SUMMARIZE -d $BASE_WORST $WORST)

      echo $(grep ^$BENCH $OUTDIR/FinalSPECSummary.csv),$MEDIAN,$BEST,$WORST,$VARIANCE,$DIFF_MEDIAN,$DIFF_BEST,$DIFF_WORST
    done >> tmpSPECSummarizer.txt
    mv tmpSPECSummarizer.txt $OUTDIR/FinalSPECSummary.csv
}

function cleanupIfNeeded {
  grep $RUN_NAME SPECSummarizerDirectories.txt > /dev/null
  UNSEEN_DIR=$?
  if [ $UNSEEN_DIR -ne 0 ]
  then
    echo $RUN_NAME >> SPECSummarizerDirectories.txt
    ls $RUN_NAME > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
      echo "Directory $RUN_NAME already exists. Overwrite (Y/N)?"
      read ANS<&1
      if echo "$ANS" | grep -i ^y
      then
        echo Overwriting...
        rm -Rf $RUN_NAME
      else
        exit 1
      fi
    fi
  fi
}

################################SCRIPT BEGINS###################################
if [ "$1" != "-o" ]
then
  echo "The -o option is mandatory as the first argument."
  exit 1
fi
shift
OUTDIR=$1
shift
ls $OUTDIR > /dev/null 2>&1 || mkdir $OUTDIR
if [[ $? -ne 0 ]]
then
  echo "Unable to create directory '$OUTDIR' that you specified as the output directory."
  exit 1
fi

# Build the summarizer executable
if which summarize >/dev/null 2>&1
then
  SUMMARIZE=$(which summarize)
else
  START_AT=$(grep -n '^#include' $0 | head -1 | cut -f1 -d:)
  END_AT=$(cat $0 | wc -l)
  CPROG_LINES=$(expr $END_AT - $START_AT)
  ((CPROG_LINES += 1))
  tail -$CPROG_LINES $0 > /tmp/summarize.cpp
  g++ /tmp/summarize.cpp -o summarize
  if [[ $? -ne 0 ]]
  then
    rm -f /tmp/summarize.cpp
    exit 1
  fi
  SUMMARIZE=./summarize
fi

rm -f SPECSummarizerDirectories.txt 2>/dev/null
# Summarize each of the individual files and put the summaries in separate dirs
while [[ -n "$1" ]]
do
  touch SPECSummarizerDirectories.txt
  FILE_TO_READ=${1#*:}
  RUN_NAME=${1%:*}
  cleanupIfNeeded
  mkdir $RUN_NAME 2>/dev/null
  grep $RUN_NAME SPECSummarizerDirectories.txt > /dev/null || echo $RUN_NAME >> SPECSummarizerDirectories.txt
  summarizeIndividualFile > $RUN_NAME/$FILE_TO_READ.SPECSummarizerSummary.txt
  echo "$RUN_NAME" > $OUTDIR/$RUN_NAME.$FILE_TO_READ
  cat $FILE_TO_READ >> $OUTDIR/$RUN_NAME.$FILE_TO_READ
  shift
done

echo "Benchmark,Baseline(Median),Baseline(Best),Baseline(Worst),Baseline(%Variance)" > $OUTDIR/FinalSPECSummary.csv
cat $(head -1 SPECSummarizerDirectories.txt)/* >> $OUTDIR/FinalSPECSummary.csv

# Combine all the individual summaries into one csv file
I=0
cat SPECSummarizerDirectories.txt | while read DIR
  do
    ((I += 1))
    if [ $I -eq 1 ]
    then
      continue
    fi
# The first one is the baseline, skip it
    echo Summarizing $DIR
    addNamedSummary $DIR
  done

# Add all the individual run summary files to the full summary
cat SPECSummarizerDirectories.txt | while read DIR
  do
    echo "$DIR" >> $OUTDIR/FinalSPECSummary.csv
    echo "Benchmark,mean,best,worst,variance" >> $OUTDIR/FinalSPECSummary.csv
    cat $DIR/* >> $OUTDIR/FinalSPECSummary.csv
  done
# Clean up
rm -Rf $(cat SPECSummarizerDirectories.txt)
rm -f /tmp/summarize.cpp ./summarize ./CurrBenchRunTimes.txt SPECSummarizerDirectories.txt
echo "Result is in file $OUTDIR/FinalSPECSummary.csv"

################################SCRIPT ENDS#####################################
exit 0
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>

double getMedian(std::vector<double> &Vec) {
  std::sort(Vec.begin(), Vec.end());
  int Size = Vec.size();
  if (!Size) return 0.;
  if (Size % 2)
    return Vec[Size/2];
  return (Vec[Size/2] + Vec[Size/2-1]) / 2;
}

// Assume the vector is sorted at this point
double getVariance(const std::vector<double> &Vec, double Median) {
  double Min = Vec[0];
  double Max = Vec[Vec.size()-1];
  return (Max - Min) / Median * 100.;
}

int main(int argc, const char **argv) {
  if (argc < 4) {
    fprintf(stderr, "Usage: %s [opt] <time1> <time2> [<time3>...]\n", argv[0]);
    fprintf(stderr, "       opt is one of -a or -d (for all or diff).\n");
    fprintf(stderr, "       The output for -a is: median,best,worst,variance.\n");
    fprintf(stderr, "       The output for -d is: ((time2-time1)/time1*100)%%.\n");
    return 1;
  }

  // Computing the diff
  if (!strcmp(argv[1], "-d")) {
    double T1 = strtod(argv[2], NULL);
    double T2 = strtod(argv[3], NULL);
    printf("%.2f%%\n", (T2-T1)/T1*100);
    return 0;
  } else if (strcmp(argv[1], "-a")) {
    fprintf(stderr, "Unrecognized option %s\n", argv[1]);
    return 1;
  }

  std::vector<double> RTSet;
  int i = 2;
  for (; i < argc; i++) {
    RTSet.push_back(strtod(argv[i], NULL));
  }
  double Median = getMedian(RTSet);
  printf("%.4f,%.4f,%.4f,%.2f%%\n", Median, RTSet[0], RTSet[RTSet.size()-1],
         getVariance(RTSet, Median));
  return 0;
}

Sunday, 19 March 2017

sed 文本替换利器

  • 首处替换
  sed 's/text/replace_text/' file   //替换每一行的第一处匹配的text
  • 全局替换
   sed 's/text/replace_text/g' file

  • 默认替换后,输出替换后的内容,如果需要直接替换原文件,使用-i:
  sed -i 's/text/repalce_text/g' file

  • 移除空白行 (here ^ 代表行头,$代表行尾):
  sed '/^$/d' file

  • 变量转换
已匹配的字符串通过标记&来引用.

$ echo this is a test line | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]


实际测试结果,并未加上[],需要调研原因:
$ echo this is en example | sed 's/\w+/[&]/g'
this is en example
  • 子串匹配标记
第一个匹配的括号内容使用标记 \1 来引用
  sed 's/hello\([0-9]\)/\1/'

  • 双引号求值
sed通常用单引号来引用;也可使用双引号,使用双引号后,双引号会对表达式求值:
  sed 's/$var/HLLOE/' 

当使用双引号时,我们可以在sed样式和替换字符串中指定变量;
eg:
p=patten
r=replaced
echo "line con a patten" | sed "s/$p/$r/g"
$>line con a replaced

  • 其它示例
字符串插入字符:将文本中每行内容(PEKSHA) 转换为 PEK/SHA
  sed 's/^.\{3\}/&\//g' file

paste 按列拼接文本



将两个文本按列拼接到一起;

cat file1
1
2

cat file2
colin
book

paste file1 file2
1 colin
2 book

默认的定界符是制表符,可以用-d指明定界符
paste file1 file2 -d ","
1,colin
2,book

Monday, 13 March 2017

How to use number expression when replacing in vim?

Here [0-9] will match any number, like local_unnamed_addr # 0, local_unnamed_addr # 1 ... local_unnamed_addr # 9 will all be replaced (here deleted actually)

:%s/local_unnamed_addr #[0-9]//gc

Friday, 10 March 2017

Spec Reducer (sreducer)

66.  How to reduce a spec test case?
Let us suppose there is a failure in h264ref benchmark.

Step1: create a build, link and run script
basically you need to create a script that just lists the compile commands,
the link command and the run command:
For example: I have a script named /home/jtony/tools/spec_reducer/buildLinkRun.sh
The build and link commands can be found by running the build.dry.sh script, this should
be run in your spec directory (like /home/jtony/scrum/s2/114/spec/cpu2006),

1(a): Here is my build command (part example):
cd /home/jtony/perf-runs/benchspec/CPU2006/464.h264ref/build/build_base_none.0000
/home/jtony/git-llvm/build/team-llvm//bin/clang -c -o annexb.o -DSPEC_CPU -DNDEBUG   -O2         -DSPEC_CPU_LINUX -fsigned-char
annexb.c &
/home/jtony/git-llvm/build/team-llvm//bin/clang -c -o biariencode.o -DSPEC_CPU -DNDEBUG   -O2         -DSPEC_CPU_LINUX -fsigned-char
     biariencode.c &
/home/jtony/git-llvm/build/team-llvm//bin/clang -c -o block.o -DSPEC_CPU -DNDEBUG   -O2         -DSPEC_CPU_LINUX -fsigned-char        b
lock.c &
/home/jtony/git-llvm/build/team-llvm//bin/clang -c -o cabac.o -DSPEC_CPU -DNDEBUG   -O2         -DSPEC_CPU_LINUX -fsigned-char        c
abac.c &
...


1(b): Here is my link command:
/home/jtony/git-llvm/build/team-llvm//bin/clang  -O2    -DSPEC_CPU_LINUX -fsigned-char   annexb.o biariencode.o block.o cabac.o configfile.o context_ini.o decoder.o explicit_gop.o fast_me.o filehandle.o fmo.o header.o image.o intrarefresh.o leaky_bucket.o lencod.o loopFilter.o macroblock.o mb_access.o mbuffer.o memalloc.o mv-search.o nal.o nalu.o nalucommon.o output.o parset.o parsetcommon.o q_matrix.o q_offsets.o ratectl.o rdopt.o rdopt_coding_state.o rdpicdecision.o refbuf.o rtp.o sei.o slice.o transform8x8.o vlc.o weighted_prediction.o specrand.o             -lm       -m64 -Wl,-q  -Wl,-rpath=/home/jtony/git-llvm/build/team-llvm//lib64 -o h264ref


1(c): the run command is a little bit harder to find, but you should be able to piece together the run
command from the speccmds.cmd file  eg:
/home/jtony/perf-runs/temp/benchspec/CPU2006/464.h264ref/run/run_base_test_none.0000/speccmds.cmd
Here is the run command for my case:
cd /home/jtony/perf-runs/benchspec/CPU2006/464.h264ref/run/run_base_test_none.0000
/home/jtony/perf-runs/benchspec/CPU2006/464.h264ref/build/build_base_none.0000/h264ref -d foreman_test_encoder_baseline.cfg > tony.out
specperl /home/jtony/scrum/s2/114/spec/cpu2006/bin/specdiff -m -l 10  --cw  --floatcompare /home/jtony/scrum/s2/114/spec/cpu2006/benchspec/CPU2006/464.h264ref/data/test/output/foreman_test_baseline_encodelog.out > tony.out


Step2, you need a good (no bug) and a bad (contains the bug) compiler. In my case, I have
The bad one   /home/jtony/git-llvm/build/team-llvm/bin/clang++
The good one  /home/jtony/git-llvm/build/good/bin/clang++
run this:
produceBinReduceScript.sh  good_compiler bad_compiler, like:
/home/nemanjai/llvm/Git/llvm-on-power/utils/produceBinReduceScript.sh tony.sh /home/jtony/git-llvm/build/good/bin/clang /home/jtony/git-llvm/build/team-llvm/bin/clang
that produced `ReduceScript.sh`


Step3, once you have the ReduceScript, you can use binary search to find which file is miscompiled. In my case I have 43, you can do the following:
like
./ReduceScript.sh 1 43
./ReduceScript.sh 1 22
./ReduceScript.sh 11 22
./ReduceScript.sh 15 22
./ReduceScript.sh 18 22
./ReduceScript.sh 18 20
./ReduceScript.sh 18 19
./ReduceScript.sh 19 19

Step 4:
go into PPCISelDAGToDAG.cpp
and add:
`"#include "EnvDecider.hpp"`
and add:
#if 1
  static EnvDecider RunMe("INSTANCE");
  if (!(++RunMe))
    return false;
#endif


Step 5:
then you can invoke the script like this (once you know how many there are):
`INSTANCE=1 ./ReduceScript.sh`
and so on and so forth

Thursday, 9 March 2017

findbadobjectfile script (learning)

#!/usr/bin/perl

@PURPOSE="Find bad compilation unit";
@SYNTAX="findbadobjectfile";
@NOTE="Uses scripts compileme, link.sh, and executeme. Also uses file object_names.";

# To use this script, create two directories: good_objects and bad_objects.
# Build the testcase twice. First build with good driver and move all the object files to good_objects directory.
# Build again with bad driver, and move all the object files to bad_objects directory.
# Create a script called link.sh which has the original link command. Remove all the object files from the link command.
# Create a file called object_names which lists all the object files, one per line.
# Create a script called executeme which runs the testcase and returns 0 for success.

sub link_program
{
  print "***Running link cmd\n";
  system("./temp_link.sh");
}

sub run_program
{
  print "****Running program\n";
  system("./executeme");
}

@obj_array = `cat object_names`;

use integer;

$lower = 0;
$size = @obj_array;
$upper = $size;
$lastgood = $size+1;

open (my $input, '<', 'link.sh');
$link = <$input>;
chomp ($link);

$j=0;
while( $lower < $upper-1 ) {
  $link_cmd = $link;

  my $link_file = "temp_link.sh";
  open (my $fh, '>',$link_file) or die "Could not open $link_file";
  system ("chmod +x temp_link.sh");

  $middle = ($lower + $upper) / 2;
  if($lower > 0){
    for($i=0;$i<$lower;$i++){
      chomp(@obj_array[$i]);
        $link_cmd = $link_cmd . " good_objects/".@obj_array[$i];
    }
  }
  for($i=$lower;$i<$middle;$i++){
    chomp(@obj_array[$i]);
    $link_cmd = $link_cmd . " good_objects/".@obj_array[$i];
  }
  for($i=$middle;$i<$upper;$i++){
    chomp(@obj_array[$i]);
    $link_cmd = $link_cmd . " bad_objects/".@obj_array[$i];
  }

  if($upper < $size){
    for($i=$upper;$i<$size;$i++){
      chomp(@obj_array[$i]);
        $link_cmd = $link_cmd . " good_objects/".@obj_array[$i];
    }
  }

  $link_cmd = $link_cmd."\n";
#   print $link_cmd;
  print $fh $link_cmd;
  close $fh;
  link_program;
  run_program;
  if($?==0){
    print "Passed round $j\n";
    $upper = $middle;
  }else{
    print "Failed round $j\n";
    $lower = $middle;
  }
  $j=$j+1;
  system("rm temp_link.sh");
}

print "Bad compilation unit: @obj_array[$lower]\n";

Tuesday, 7 March 2017

用tr 命令进行转换



  • 通用用法

  echo 12345 | tr '0-9' '9876543210' //加解密转换,替换对应字符
  cat text| tr '\t' ' '  //制表符转空格

  • tr删除字符

  cat file | tr -d '0-9' // 删除所有数字

  • -c 求补集

  cat file | tr -c '0-9' //获取文件中所有数字
  cat file | tr -d -c '0-9 \n'  //删除非数字数据

  • tr压缩字符
tr -s 压缩文本中出现的重复字符;最常用于压缩多余的空格

  cat file | tr -s ' '

  • 字符类
tr中可用各种字符类:
alnum:字母和数字
alpha:字母
digit:数字
space:空白字符
lower:小写
upper:大写
cntrl:控制(非可打印)字符
print:可打印字符
使用方法:tr [:class:] [:class:]

  eg: tr '[:lower:]' '[:upper:]'

Friday, 3 March 2017

auto test case generator

$ cat b.c
__IN__ glob;
__RET__ test___NM__(__IN__ a, __IN__ b) {
  return a __OPC__ b;
}

__RET__ test___NM___sext(__IN__ a, __IN__ b) {
  return -(a __OPC__ b);
}

__RET__ test___NM___z(__IN__ a) {
  return a __OPC__ 0;
}

__RET__ test___NM___sext_z(__IN__ a) {
  return -(a __OPC__ 0);
}

void test___NM___store(__IN__ a, __IN__ b) {
  glob = (a __OPC__ b);
}

void test___NM___sext_store(__IN__ a, __IN__ b) {
  glob = -(a __OPC__ b);
}

void test___NM___z_store(__IN__ a) {
  glob = (a __OPC__ 0);
}

void test___NM___sext_z_store(__IN__ a) {
  glob = -(a __OPC__ 0);
}

$ cat getTCs.sh
for ret in int 'long long'
do
  for input in 'signed char' 'unsigned char' 'signed short' 'unsigned short' 'signed int' 'unsigned int' 'signed long long' 'unsigned long long'
  do
    for opc in '==' '!=' '<' '>' '<=' '>='
    do
      NAME=$(echo $ret | sed 's/int/i/;s/long long/ll/;')
      NAME=$NAME$(echo $opc | sed 's/==/eq/;s/!=/ne/;s/<=/le/;s/>=/ge/;s/</lt/;s/>/gt/;')
      NAME=$NAME$(echo $input | sed 's/unsigned/u/g;s/signed/s/g;s/char/c/g;s/short/s/g;s/int/i/g;s/long long/ll/g;s/ //g;')
      echo NAME: $NAME
      sed "s/__RET__/$ret/g;s/__IN__/$input/g;s/__OPC__/$opc/g;s/__NM__/$NAME/g;" b.c > testCompares$NAME.c
    done
  done
done

$ ./getTCs.sh
$ ls testCompares* | while read FILE; do echo '#if 0' > tmp; echo "GCC generated code:" >> tmp; \
/home/llvm/gcc/install/gcc-6.2.0/bin/gcc -O2 -S -o - $FILE >> tmp; echo '#endif' >> tmp; cat tmp >> $FILE; done

Saturday, 4 February 2017

get only the option value in shell script option

What does i#*= mean in the following shell script snippet?

case $i in
        --flags=*)
            FLAGS="$FLAGS${i#*=} "


Here it means attach  the part after symbol '=' of $i to FLAGS.

For example, Let us assume $i is --flags=BBB  if originally FLAGS='AAA ' before executing this line,  after execution, it would become   FLAGS='AAA BBB '

Saturday, 28 January 2017

shift command

shift is a bash built-in which kind of removes arguments in beginning of the argument list. Given that the arguments provided to the script are 3 available in $1, $2, $3, then a call to shift will make $2 the new $1. a shift 2 will shift by two making new $1 the old $3. for more info see here

Tuesday, 3 January 2017

Shell Script 15 Regular Expressions - User Guide (c)

POSIX Character Class Definitions

POSIX 1003.2 section 2.8.3.2 (6) defines a set of character classes that denote certain common ranges. They tend to look very ugly but have the advantage that also take into account the 'locale', that is, any variant of the local language/coding system. Many utilities/languages provide short-hand ways of invoking these classes. Strictly the names used and hence their contents reference the LC_CTYPE POSIX definition (1003.2 section 2.5.2.1).

Value

Meaning

[:upper:]Any alpha character A to Z.
[:lower:]Any alpha character a to z.
[:digit:]Only the digits 0 to 9
[:blank:]Space, TAB characters only.
[:xdigit:]Hexadecimal notation 0-9, A-F, a-f.
[:punct:]Punctuation symbols . , " ' ? ! ; : # $ % & ( ) * + - / < > = @ [ ] \ ^ _ { } | ~
[:cntrl:]Control Characters NL CR LF TAB VT FF NUL SOH STX EXT EOT ENQ ACK SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC IS1 IS2 IS3 IS4 DEL.
[:space:]Any whitespace characters (space, tab, NL, FF, VT, CR). Many system abbreviate as \s.
[:alnum:]Any alphanumeric character 0 to 9 OR A to Z or a to z (the set defined by upper, lower and digit)
[:alpha:]Any alpha character A to Z or a to z (the set defined by upper and lower).
[:print:]Any printable character (set defined by alnum and punct) plus the single character SPACE.
[:graph:]Any printable characters (set defined by alnum and punct) but excludes the single character SPACE. Many system abbreviate as \W.
These are always used inside square brackets in the form [[:alnum:]] or combined as [[:digit:]a-d]

Monday, 2 January 2017

Shell Script 14 Regular Expressions - User Guide (b)

Metacharacter

Meaning

?The ? (question mark) matches when the preceding character occurs 0 or 1 times only, for example, colou?r will find both color (u is found 0 times) and colour (u is found 1 time).
*The * (asterisk or star) matches when the preceding character occurs 0 or more times, for example, tre* will find tree (e is found 2 times) and tread (e is found 1 time) and trough (e is found 0 times and thus returns a match only on the tr).
+The + (plus) matches when the preceding character occurs 1 or more times, for example, tre+ will find tree (e is found 2 times) and tread (e is found 1 time) but NOT trough (0 times).
{n}Matches when the preceding character, or character range, occurs n times exactly, for example, to find a local phone number we could use [0-9]{3}-[0-9]{4} which would find any number of the form 123-4567. Value is enclosed in braces (curly brackets).Note: The - (dash) in this case, because it is outside the square brackets, is a literal. Louise Rains writes to say that it is invalid to commence a NXX code (the 123) with a zero (which would be permitted in the expression above). In this case the expression [1-9][0-9]{2}-[0-9]{4} would be necessary to find a valid local phone number.
{n,m}Matches when the preceding character occurs at least n times but not more than m times, for example, ba{2,3}b will find baab and baaab but NOT bab or baaaab. Values are enclosed in braces (curly brackets).
{n,}Matches when the preceding character occurs at least n times, for example, ba{2,}b will find 'baab', 'baaab' or 'baaaab' but NOT 'bab'. Values are enclosed in braces (curly brackets).

Examples:
            (1)
jtony@genoa:~/learn/shell/UserGuide$ grep -rn  --color 'W*in' string1.txt
1:Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
2:Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)
jtony@genoa:~/learn/shell/UserGuide$ grep -rn  --color 'W*in' string2.txt
1:Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
2:Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)

(2):
egrep -rn --color '[xX][0-9a-z]{2}'  string2.txt
2:Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)
 


Sunday, 1 January 2017

Shell Script 13 Regular Expressions - User Guide (a)

Metacharacter

Meaning


^The ^ (circumflex or caret) inside square brackets negates the expression (we will see an alternate use for the circumflex/caret outside square brackets later), for example, [^Ff] means anything except upper or lower case F and [^a-z] means everything except lower case a to z.
Notes:
  1. There are no spaces between the range delimiter values, if there was, depending on the range, it would be added to the possible range or rejected as invalid. Be very careful with spaces.
  2. Some regular expression systems, notably VBScript, provide a negation operator (!) for use with strings. This is a non-standard feature and therefore the resulting expressions are not portable.
  3. Because of the dual nature of the caret (or circumflex) you will frequency see expressions like [^"], [^<] or [^,] which are typically used as separator triggers (when combined with iterations) for more more complex searches or when parsing, say, HTML or comma delimited text.
e.g.

jtony@genoa:~/learn/shell/UserGuide$ cat string1.txt
Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)
jtony@genoa:~/learn/shell/UserGuide$ cat string2.txt
Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)

jtony@genoa:~/learn/shell/UserGuide$ grep -rn  '[^A-M]in'  string1.txt
1:Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)

jtony@genoa:~/learn/shell/UserGuide$ grep -rn  '[A-Za-z]in'  string1.txt
1:Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
2:Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)








This series refer the online article:
http://www.zytrax.com/tech/web/regex.htm#search

Shell Script 13 : Regular Expression (c)

You can also for matches that appear at the beginning or end of words, not whole lines.
jtony@genoa:~/learn/shell$ cat test
specialize
aaaaaaaaaa
tomcat
tom
atom
tom333
jyjtom
specialise
jtony@genoa:~/learn/shell$ grep '\<tom' test
tomcat
tom
tom333
jtony@genoa:~/learn/shell$ grep 'tom\>' test
tom
atom
jyjtom

Saturday, 31 December 2016

Shell Script 12 : Regular Expression (b)

How to search a string located at the beginning or the end of a line?
jtony@genoa:~/learn/shell$ cat test
specialize
aaaaaaaaaa
tomcat
tom
atom
tom333
jyjtom

specialise

(a) Using a caret (outside of brackets) allows you to designate the “beginning” of a line.
jtony@genoa:~/learn/shell$ grep '^tom' test
tomcat
tom
tom333

(b) To search for the end of a line, use the dollar sign.
jtony@genoa:~/learn/shell$ grep 'tom$' test
tom
atom

jyjtom

(c) To search for both the beginning and the end of a line, i.e., searach lines only contains 'tom'
jtony@genoa:~/learn/shell$ grep '^tom$' test
tom