Awk

From Attie's Wiki
(Difference between revisions)
Jump to: navigation, search
m (Created page with 'This page contains some example awk scripts. ==8-bit ADC battery voltage reading== Contents of <code>minicom.cap</code>: <source lang="text"> 160 159 159 159 158 158 158 158 157…')
 
m (Convert Hex input to raw binary)
 
(22 intermediate revisions by one user not shown)
Line 1: Line 1:
 
This page contains some example awk scripts.
 
This page contains some example awk scripts.
 +
 +
Set a variable for use inside the script like so:
 +
<source lang="bash">
 +
awk -v variable=text '{..}'
 +
</source>
 +
 +
==Reverse fields on a line basis==
 +
<source lang="bash">
 +
echo -e "a.b.c\nd.e\nf.g.h.i" | \
 +
  awk -F . '{
 +
              i=NF;
 +
              do {
 +
                printf $(i);
 +
                if (i>1) {
 +
                  printf FS;
 +
                } else {
 +
                  printf "\n";
 +
                }
 +
              } while(--i > 0);
 +
            }'
 +
</source>
 +
 +
==Convert Hex input to raw binary==
 +
Given the following input, output a binary file where each byte represents the values listed here
 +
<source lang="bash">
 +
cat <<EOF | awk -b '{printf "%c", strtonum($0)}'
 +
0x68
 +
0x65
 +
0x6c
 +
0x6c
 +
0x6f
 +
0x0a
 +
EOF
 +
</source>
 +
 +
==Find the total number of lines of source code==
 +
<source lang="bash">
 +
for i in `find -type f -name '*.c'`; do
 +
  cat $i
 +
done | \
 +
  awk 'BEGIN{lines=0}
 +
            {lines++}
 +
        END{printf "lines: %d\n", lines}'
 +
</source>
 +
===categorized===
 +
<source lang="bash">
 +
for i in `find -type f -name '*.c'`; do
 +
  cat $i | tr -d ' \t'
 +
done | \
 +
  awk 'BEGIN{lines=0; empty=0; pp=0; comment=0}
 +
            {
 +
              lines++;
 +
              if ($0 == "") empty++;
 +
              if (substr($0,0,1) == "#") pp++;
 +
              if (substr($0,0,2) == "//") comment++;
 +
            }
 +
        END{
 +
              printf " total lines: %d\n", lines;
 +
              printf "      empty: %d\n", empty;
 +
              printf "preprocessor: %d\n", pp;
 +
              printf " c++ comment: %d\n", comment;
 +
              printf "      remain: %d\n", lines - empty - pp - comment;
 +
            }'
 +
</source>
 +
 +
==Bin2C==
 +
Convert a binary file to C source
 +
<source lang="bash">
 +
FILE=icon.bmp
 +
 +
cat ${FILE} | \
 +
  hexdump -ve '/1 "%02X\n"' | \
 +
  awk 'BEGIN{
 +
              i=0; l=16; f=1;
 +
              printf "unsigned char mybin[] = {\n";
 +
            }
 +
            {
 +
              if (i == 0) {
 +
                if (f == 0) printf ",\n";
 +
                printf"\t";
 +
              }
 +
              if (i > 0) printf ", ";
 +
              printf "0x%s", $1;
 +
              i++;
 +
              if (i == l) i=0;
 +
              f=0
 +
            }
 +
        END{
 +
              printf "\n};\n"
 +
            }'
 +
</source>
 +
 +
==Calculate size of all source in directory (using ls and bc)==
 +
<source lang="bash">
 +
find . -type f -name '*.c' -exec ls -l {} \; | \
 +
  tr -s ' ' | \
 +
  cut -d ' ' -f 5 | \
 +
  awk 'BEGIN{i=0}
 +
            {if (i) printf "+"; i = 1; printf $1}
 +
        END{printf "\n"}' | \
 +
  bc
 +
</source>
 +
===Without tr, cut or bc===
 +
Notice the speed difference between this, and the previous example.
 +
<source lang="bash">
 +
ls -l `find . -type f -name '*.c'` | \
 +
  awk 'BEGIN{bytes=0}
 +
            {bytes+=$5}
 +
        END{printf "%d bytes\n", bytes}'
 +
</source>
 +
 +
===With 'auto-ranging'===
 +
<source lang="bash">
 +
ls -l `find . -name '*.c'` | \
 +
  awk 'BEGIN{i=0}
 +
            {i+=$5}
 +
        END{f = 0;
 +
            while (i > 1024) { i /= 1024; f++ }
 +
            printf "%0.2f ", i
 +
            if      (f == 0) print "bytes";
 +
            else if (f == 1) print "kB";
 +
            else if (f == 2) print "MB";
 +
            else if (f == 3) print "GB";
 +
            else if (f == 4) print "TB";
 +
            else            print "x10^" f
 +
            }'
 +
</source>
  
 
==8-bit ADC battery voltage reading==
 
==8-bit ADC battery voltage reading==
Line 31: Line 158:
 
Command:
 
Command:
 
<source lang="bash">
 
<source lang="bash">
cat minicom.cap | sort -r | uniq -c | awk 'BEGIN{tot=0; printf "hh:mm\tvoltage\n"}{tot += $1; printf "%2d:%02d\t%.2fv\n", ($1/60), ($1%60), (((3.3 / 256) * $2) * 2)}END{printf "Total: %d:%02d\n", (tot/60), (tot%60)}'
+
cat minicom.cap | sort -r | uniq -c | \
 +
  awk 'BEGIN{tot=0; printf "hh:mm\tvoltage\n"}
 +
            {tot += $1; printf "%2d:%02d\t%.2fv\n", ($1/60), ($1%60), (((3.3 / 256) * $2) * 2)}
 +
        END{printf "Total: %d:%02d\n", (tot/60), (tot%60)}'
 
</source>
 
</source>
  
Line 45: Line 175:
 
  0:05  3.97v
 
  0:05  3.97v
 
Total: 0:24
 
Total: 0:24
 +
</source>
 +
 +
==Little Helper==
 +
When building a large package, you may find that you need to do the same thing to multiple subdirectories.
 +
This script can be used in that situation.
 +
<source lang="bash">
 +
script
 +
make -k
 +
^D
 +
cat typescript  | awk -- 'BEGIN{catch=0}{if ($4 == "Error") { catch=1 } else if (catch == 1 && $2 == "Leaving" && $3 == "directory") { print $4; catch = 0}}' | sed -re 's/^`//' -e "s/'.$/"
 +
</source>
 +
 +
==Get a list of Picasa's Starred Files==
 +
<source lang="bash">
 +
find . -name '.picasa.ini' | \
 +
while read i; do
 +
  I=$(dirname "${i}")
 +
  cat "${i}" | \
 +
    dos2unix | \
 +
    awk 'BEGIN{k=0;f=""}{if(substr($0,0,1)=="["){f=substr($0,2,length($0)-2)}else if($0=="star=yes"){print f}}' | \
 +
    while read i; do
 +
      echo ${I}/${i}
 +
    done
 +
done
 
</source>
 
</source>

Latest revision as of 23:21, 17 August 2014

This page contains some example awk scripts.

Set a variable for use inside the script like so:

awk -v variable=text '{..}'

Contents

[edit] Reverse fields on a line basis

echo -e "a.b.c\nd.e\nf.g.h.i" | \
  awk -F . '{
              i=NF;
              do {
                printf $(i);
                if (i>1) {
                  printf FS;
                } else {
                  printf "\n";
                }
              } while(--i > 0);
            }'

[edit] Convert Hex input to raw binary

Given the following input, output a binary file where each byte represents the values listed here

cat <<EOF | awk -b '{printf "%c", strtonum($0)}'
0x68
0x65
0x6c
0x6c
0x6f
0x0a
EOF

[edit] Find the total number of lines of source code

for i in `find -type f -name '*.c'`; do
  cat $i
done | \
  awk 'BEGIN{lines=0}
            {lines++}
         END{printf "lines: %d\n", lines}'

[edit] categorized

for i in `find -type f -name '*.c'`; do
  cat $i | tr -d ' \t'
done | \
  awk 'BEGIN{lines=0; empty=0; pp=0; comment=0}
            {
              lines++;
              if ($0 == "") empty++;
              if (substr($0,0,1) == "#") pp++;
              if (substr($0,0,2) == "//") comment++;
            }
         END{
              printf " total lines: %d\n", lines;
              printf "       empty: %d\n", empty;
              printf "preprocessor: %d\n", pp;
              printf " c++ comment: %d\n", comment;
              printf "      remain: %d\n", lines - empty - pp - comment;
            }'

[edit] Bin2C

Convert a binary file to C source

FILE=icon.bmp
 
cat ${FILE} | \
  hexdump -ve '/1 "%02X\n"' | \
  awk 'BEGIN{
              i=0; l=16; f=1;
              printf "unsigned char mybin[] = {\n";
            }
            {
              if (i == 0) {
                if (f == 0) printf ",\n";
                printf"\t";
              }
              if (i > 0) printf ", ";
              printf "0x%s", $1;
              i++;
              if (i == l) i=0;
              f=0
            }
         END{
              printf "\n};\n"
            }'

[edit] Calculate size of all source in directory (using ls and bc)

find . -type f -name '*.c' -exec ls -l {} \; | \
  tr -s ' ' | \
  cut -d ' ' -f 5 | \
  awk 'BEGIN{i=0}
            {if (i) printf "+"; i = 1; printf $1}
         END{printf "\n"}' | \
  bc

[edit] Without tr, cut or bc

Notice the speed difference between this, and the previous example.

ls -l `find . -type f -name '*.c'` | \
  awk 'BEGIN{bytes=0}
            {bytes+=$5}
         END{printf "%d bytes\n", bytes}'

[edit] With 'auto-ranging'

ls -l `find . -name '*.c'` | \
  awk 'BEGIN{i=0}
            {i+=$5}
         END{f = 0;
             while (i > 1024) { i /= 1024; f++ }
             printf "%0.2f ", i
             if      (f == 0) print "bytes";
             else if (f == 1) print "kB";
             else if (f == 2) print "MB";
             else if (f == 3) print "GB";
             else if (f == 4) print "TB";
             else             print "x10^" f
            }'

[edit] 8-bit ADC battery voltage reading

Contents of minicom.cap:

160
159
159
159
158
158
158
158
157
156
157
156
156
156
155
155
155
155
154
154
154
154
154

Command:

cat minicom.cap | sort -r | uniq -c | \
  awk 'BEGIN{tot=0; printf "hh:mm\tvoltage\n"}
            {tot += $1; printf "%2d:%02d\t%.2fv\n", ($1/60), ($1%60), (((3.3 / 256) * $2) * 2)}
         END{printf "Total: %d:%02d\n", (tot/60), (tot%60)}'

Output:

hh:mm   voltage
 0:01   4.12v
 0:03   4.10v
 0:04   4.07v
 0:02   4.05v
 0:04   4.02v
 0:04   4.00v
 0:05   3.97v
Total: 0:24

[edit] Little Helper

When building a large package, you may find that you need to do the same thing to multiple subdirectories. This script can be used in that situation.

script
make -k
^D
cat typescript  | awk -- 'BEGIN{catch=0}{if ($4 == "Error") { catch=1 } else if (catch == 1 && $2 == "Leaving" && $3 == "directory") { print $4; catch = 0}}' | sed -re 's/^`//' -e "s/'.$/"

[edit] Get a list of Picasa's Starred Files

find . -name '.picasa.ini' | \
while read i; do
  I=$(dirname "${i}")
  cat "${i}" | \
    dos2unix | \
    awk 'BEGIN{k=0;f=""}{if(substr($0,0,1)=="["){f=substr($0,2,length($0)-2)}else if($0=="star=yes"){print f}}' | \
    while read i; do
      echo ${I}/${i}
    done
done
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox