转 awk 使用方法

 

ps -ef|grep  oracleepprod |grep -v grep|awk ' { print $2 }'|xargs kill -9 

 

unix: 指定行 输入文字

###

$ cat 1
aaa

 


## add print before aaa ,选取开头是aaa的行,加入以下行道aaa的行之前 #####
awk '/^aaa/{print "export TESTGJS=D605C35198D2CA085E9C6FA7D2DF69F3;"}1' 1
export TESTGJS=D605C35198D2CA085E9C6FA7D2DF69F3;
aaa
## add export.. before aaa #####
awk '/^aaa/{print "export ..."}1' 1
export ...
aaa

 

###选取某一行是None的行,前面加入export 

 awk '/None/{print "         export ..."}1' setogg.sh.peng > 1

 

 #####编辑/etc/hosts  屏蔽某一行主机 ,找到IP 10.241.131.126,然后在ip 10.241.131.126 前面加入# 将其屏蔽,参考文档 

https://blog.csdn.net/enemyisgodlike/article/details/50723876?utm_term=shell%E8%84%9A%E6%9C%AC%E9%85%8D%E7%BD%AEhosts%E6%96%87%E4%BB%B6&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-0-50723876&spm=3001.4430

 

按照ed ,备份文件,开始修改

yum install ed
cp /etc/hosts /etc/hosts.1234
(echo ',s/10.241.131.126/#10.241.131.126/';echo '.';echo 'wq')|ed hosts

 

#####awk:
#####awk '{gsub(/a..e/,"替换内容或为空");print}' 文件名
####同上,替换项 写成空字符串就能实现删除功能。

 awk '{gsub(/table/,"##table");print}'  $OGG_BIN/dirprm/p_test.prm

 

 

 

##sample 2


##感谢小林coding/ 小林coding韩智杰_生信/timer_go

https://jingyan.baidu.com/article/9158e000038877a2541228be.html  

awk 提取列满足要求的行


https://blog.csdn.net/qq_34827674/article/details/99685026?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf

Linux shell获得字符串所在行数及位置

 

02 获取字符串中字符所在的位置
方式一:用awk -F 和 wc -c 组合
[root@root]# echo 'uellevcmpottcap' | awk -F 'ott' '{print $1}';
uellevcmp
[root@root]# echo 'uellevcmpottcap' | awk -F 'ott' '{print $1}' | wc -c
10
1
2
3
4
方式二:用awk 'BEGIN{print index("'${str}'","'${str1}'") }'
[root@root]# str='uellevcmpottcap';str1='ott';awk 'BEGIN{print index("'${str}'","'${str1}'") }'
10
————————————————
版权声明:本文为CSDN博主「小林coding」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34827674/article/details/99685026

 

##sample 2.2.

##使用 空格 或者: 作为分隔符,或者无数个空格或者: 分隔,同时 匹配行内包含 '/[m]ysql/ 这一行,m可以大写。找第5列

netstat -tpln | awk -F "[ : ]+" ' /[m]ysql/ {print $5}'

 

[] 中间带有2个字符,一个字符是:,一个字符是空格


https://www.cnblogs.com/muahao/p/6874412.html

 

###samlple 33

shell awk求和 当第一列相同时,对应的第二列相加


awk '{sum[$1]+=$2}END{for(c in sum){print c,sum[c]}}' 1.txt


shell awk求和 当第一列相同时,对应的第4列相加
awk '{sum[$1]+=$4}END{for(c in sum){print c,sum[c]}}' 2.log

 

############sample 34

#http://blog.sina.com.cn/s/blog_9a1f7cf80102wrpf.html

 

awk之获取匹配两个关键字之间的行(不包括关键字行)

 

文本:
1
2
3
4
5
6
7
8
9

获取3和7之间的内容:
4
5
6
  1. awk '/3/,/7/{if(i>1)print x;x=$0;i++}' file
  2. 4
  3. 5
  4. 6
[解析]
   获取2个关键字之间的内容大家都会想到正则匹配的 /i/,/j/ 这样的语句,但是这会把包含3和7的行都打印出来,我们的问题是截取它们之间的内容,那肯定还需要进行处理,这个是斩头去尾的思路。


  1. seq 9 |sed -n '/3/,/7/{/3/n;/7/b;p}'
  2. 4
  3. 5
  4. 6

 

 

 

两个sed小技巧:sed "/变量/变量/"

 

两个sed小技巧

 

 

###去除掉所有第四列为-的行,也就是不在机械臂的行
awk '!($4=="-")' all_tape_in_pool.txt

###去除掉从DD_TO_DD pool 到 long_retention_pool pool 中间的行

begin=`cat all_tape_in_pool.txt | grep -n "DD_TO_DD pool" | awk -F ":" '{print $1}'`
end=`cat all_tape_in_pool.txt | grep -n "long_retention_pool pool" | awk -F ":" '{print $1}'`

beg1=`expr $begin + 1`
end1=`expr $end - 1`

sed -i ""$beg1","$end1"d" all_tape_in_pool.txt

 

 

Shell编程-awk 



简介

awk 是一种对立的编程语言,集成于所有UNIX/Linux中,这个名字是它创建者的名字首字母组成的 Alfred Aho,Peter Weinberger, and Brian Kernighan。

awk的基本语法

普通模式

awk '/pattern/{action}' files

其中patter是一个正则表达式,action又是一系列命令,对于满足匹配的文本执行一些动作,files表示待操作的文件,如果不指定,则输入是STDIN。如果不指定pattern,则对所有文件的每一行都执行action。

表达式模式

当在awk中使用比较操作符时,使用下面的语法模式,详见后面。

awk '(expression){action}' files

有如下一个示例文件

zdd.txt包含如下内容
Fruit Price/lbs
Banana 0.89
Paech 0.79
Kiwi 1.50
Pineapple 1.29
Apple 0.99

显示一个文件的所有行

awk '{ print ; }' zdd.txt 

分号表示命令结束,这个例子没有pattern,只有action

域编辑

awk自动将读入的行分割成域(field),域是由一个或多个分隔符分割开的字符集,缺省的分隔符是tab和空格,访问域可以用$1,$2, ... $n的形式,域都是从1开始的,而$0表示整个行(以行本来的面目呈现)

格式化输出水果及价格

awk '{ printf "%-15s %s\n", $1, $2 ;}' zdd.txt

输出如下

Fruit           Price/lbs
Banana          0.89
Paech            0.79
Kiwi              1.50
Pineapple      1.29
Apple            0.99

使用其他的域分隔符

awk的-F参数可以制定其他的域分隔符,比如下面的代码将打印D

echo A:B:C:D | awk -F: '{print $4}'

多个命令同时执行

在价格高于1美元的水果后面加* 以引起注意,这里包含了两个模式和动作对,直接书写即可,不必像sed那样加-e参数

awk '/[1-9]\.[0-9][0-9]$/ { print $0, "*"} /0\.[1-9][1-9]/ {print ;}' zdd.txt

输出如下

Banana 0.89
Paech 0.79
Kiwi 1.50 *
Pineapple 1.29 *
Apple 0.99
bash-3.2$

比较操作

awk中可以执行的比较操作有
<
>
<=
>=
!=
value ~ /pattern/
value !~ /pattern/

比较操作基本语法

awk '(expression){action}' files

其中expression是一个比较表达式,通常将其用括弧括起来。

在价格大于1美元的水果后面打印expensive

awk '$2 >= 1.0 { printf "%s\t%s\n", $0, "Expensive" ; }' zdd.txt

输出

Fruit Price/lbs Expensive
Kiwi 1.50       Expensive
Pineapple 1.29  Expensive

复合表达式

可以使用&&或||连接多个表达式,表达式用()扩起
(expr1) && (expr2) 
(expr1) ||(expr)

next命令
看一个例子
awk '
$3 <= 75 { printf "%s\t%s\n",$0,"REORDER" ; }
$3 > 75 { print $0 ; }
' zdd.txt
这个命令的执行过程如下
(1) 读入一行,检查价格是否小于等于75,如果为真,则打印出REORDER 
(2) 检查该行是否大于75,如果大于则直接打印
(3) 处理下一行
可见如果条件(1)满足,则不必再判断条件(2)了,如果避免这个多余的操作呢?使用next即可
awk '
$3 <= 75 { printf "%s\t%s\n",$0,"REORDER" ; next ; }
$3 > 75 { print $0 ; }
' zdd.txt

BEGIN和END

基本与法

awk '
    BEGIN { actions }
    /pattern/ { actions }
    /pattern/ { actions }
    END { actions }
' files

注意BEGIN对应的模式必须是第一个模式,而END对应的模式必须是最后一个模式。这两者都不参与文本行的处理,只是做一些初始化及善后工作。

BEGIN可以用来打印表头或者列名等,如下


复制代码
BEGIN{
-F":"
printf "----------------------------------------------------------------\n"
printf "%-20s%-16s  Jan  |  Feb  |  Mar  |Total Donated\n ","NAME","PHONE"
printf "----------------------------------------------------------------\n"
}

复制代码

7 以STDIN作为输入
打印文件名及大小,在ls命令的输出中,文件名位于第9列,而大小位于第5列
ls -l | awk '{ printf "%15s%15s\n", $9, $5}'
          ipck           1853
     ipcrm.exe           5632
      ipcs.exe          14336
      join.exe          52224
      kill.exe          10240
      less.exe         168960
  lessecho.exe           6144
   lesskey.exe           9728
      link.exe          42496
     lkbib.exe          52224
        ln.exe         114688
    locate.exe         122880
     login.exe          20992
   logname.exe          41472
   lookbib.exe          51712
       lpr.exe         299008
        ls.exe         122368
  makeinfo.exe         191488
       man.exe          37376
       man2dvi            409
  man2html.exe          45568
       manlint           7098

流控制

if

基本格式

if (expression1) {
    action1
} else if (expression2) {
    action2
} else {
    action3
}

一个例子,根据每行的特征字,在行末加注释。


复制代码
awk '{ 
    print "%s\t", $0;
    if ($1 ~ /d/) {
        print "Directory\n";
    }
    else if ($NF ~ /\.pl/){
        print "Perl script\n";
    }
    else if ($NF ~ /\.bcp/) {
        print "BCP file\n";
    }
    else {
        print "\n";
    }
}'

复制代码

while

for

awk中的for与C语言中的for类似。

awk '{ 
    for (x = 1; x <= NF; x++){
        printf "%s ", $x;
    }
    print "\n";
}' input_file ;

特殊技巧

NR==FNR

这条语句只有在输入是多个文件的时候才有意义,用来判断当前正在处理第一个文件。

NR    处理过的文件行数,多个文件累加。

FNR  处理过的文件行数,仅限当前文件。

所以,NR >= FNR。看一个例子

#cat a
张三|000001
李四|000002

#cat b
000001|10
000001|20
000002|30
000002|15
 
想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:

张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15

awk -F'|' 'NR==FNR{a[$2]=$0;next}{print a[$1] FS $2}' a b
awk -F'|' '{a[$2]=$0}NR>FNR{print a[$1] FS $2}' a b

[解析]
由NR=FNR成立,判断当前读入的是第一个文件a,然后使用{a[$2]=$0;next}循环将a文件的每行记录都存入数组a,并使用$2作为下标引用.next,不在执行后面的语句.
由 NR=FNR不成立,判断当前读入了第二个文件b,然后跳过{a[$2]=$0;next},对第二个文件b的每一行都无条件执行{print a[$1]FS$2},此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件的$2为数组下标相同.因此可以在此输出该数组的值。 下面那种写法是不是更短呢?

awk应用

按条件打印文件

awk配合ls命令可以打印文件指定的某一列,ls -l的输出入下

-rwxr-xr-x   1 user1     staff       1805 Dec  4 22:59 abc.sh
drwxr-xr-x   3 user2     staff        512 Dec  4 22:59 test_report
-rwxr-xr-x   1 user3     staff      12526 Feb  1 03:12 test.pl
drwxr-xr-x   3 user1     staff        512 Feb  1 03:19 xyz

如果只想打印文件名(第九列),那么可以使用下面的方法,$9表示文本行的第九列。

ls -l | awk '{print $9;}'

如果只想打印user1创建的文件名,可以使用下面的方法,这里/user1/是一个pattern,表示只处理包含user1的文本行。

ls -l | awk '/user1/{print $9;}'

格式化打印

awk支持printf格式化打印。

只打印文件名和文件大小(文件名位于第9列,文件大小位于第5列)

ls -l | awk '{print $9, $5;}'

上面的代码虽然能打印,但是格式很乱,可以使用printf格式化一下。

%s参数,用来打印字符串,可以指定宽度,不足的补空格,正数表示右对齐,负数表示左对齐。%3s表示字符串宽度为3列,右边对齐,如果字符串实际宽度大于3,那么取实际宽度。

文件名左对齐,大小左对齐

ls -l | awk '{printf "%-16s%\t%-16s\n", $9, $5;}'

文件名左对齐,大小右对齐

ls -l | awk '{printf "%-16s%\t%16s\n", $9, $5;}'

文件名右对齐,大小左对齐

ls -l | awk '{printf "%16s%\t%-16s\n", $9, $5;}'

文件名右对齐,大右左对齐

ls -l | awk '{printf "%16s%\t%16s\n", $9, $5;}'

按行打印环境变量PATH

echo $PATH | awk -F: ' {
    for (i = 1; i <=NF; i++) {
        printf "%s\n", $i;
    }
}'

删除某个用户的所有文件

删除用户zdd的所有文件,注意-rf后面有一个空格。

ls -l | awk '/zdd/{print "rm -rf " $9} | sh


my sample:


##purpose small script to check
## print sid
ps -ef|grep pmon|grep -v grep| awk ' { print $9 } '| awk -F_ ' { print $3 } ' | sort -rn > /tmp/sid.txt
cat /tmp/sid.txt| while read line
do
sid=`echo $line`
grep $sid /etc/oratab
done

 

 

posted @ 2016-11-14 14:56  feiyun8616  阅读(419)  评论(0编辑  收藏  举报