编shell脚本遇到一个问题,awk能切割掉最后一个字段的值嘛?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编shell脚本遇到一个问题,awk能切割掉最后一个字段的值嘛?相关的知识,希望对你有一定的参考价值。

如这个路径“/usr/share/man/man5/locale.alias.5.gz ”
我以“/”作为分隔符,去掉最后一个字段变成“/usr/share/man/man5/”要怎么写?

先设个变量:
path=/usr/share/man/man5/locale.alias.5.gz

法一,bash中特有的字符串分割法:
echo $path%/*/

法二,sed中的s替换命令,利用了*在正则中的贪婪特性:
echo $path | sed 's#\(.*/\).*#\1#'

法三,awk字段分割重组:
echo $path | awk -F/ 'for(i=1;i<NF;i++)printf("%s/",$i);printf("\n")'
参考技术A awk 'NF-=1' FS="/" OFS="/"

即可

希望采纳~

这么简单的命令就能完成,楼上还能写出一堆废话....
参考技术B /usr/share/man/man5/locale.alias.5.gz | awk -F"/" 'printf "/%s/%s/%s/%s/\n",$2,$3,$4,$5 '

如果整个字符串长度不定的话,man5固定的话,可以采用if($NF=="man5")来判断需要几个字段进行拼接。

shell 脚本awk的高级应用之

需求:

文本中第一列字符相等时,第二列相加 ,最后输出字符和最后的和(为了方便最后核对,都给了1)

文本如下:

cat test.log
abc 1
aaa 1
bbb 1
ddd 1
sss 1
iii 1
abc 1
sss 1
ddd 1
ddd 1
ddd 1
ddd 1
bbb 1
bbb 1
bbb 1
bbb 1
bbb 1

思路1: awk把第一列取出,然后排序sort,去重uniq,赋值给变量x,然后遍历x,从文本中grep,然后awk截取第二列并相加,这个思路需要多次awk,多次读文件,效率较慢,思考着能不能一次读取就搞定呢,于是思路2


思路2: cat文本后sort,按照第一列排序,这样相等的就连续出现,不相等时说明是下一个了,于是awk读入,判断第一列是否跟上次相等,相等则加;不等则打印total;注意首行和末行


思路2代码:

#!/bin/bash

cat test.log|sort|awk ‘BEGIN{      #排序文本,并读入
tmp = ""
total = 0     
}
{
if (tmp==$1)         #当相等时相加
{
        total += $2
}
else{                         #不相等时,打印上次的相加值
        if (tmp!=""){         #处理首行,当首行时,没有上一次,所以需要排除
        print tmp " total is : " total #打印
        }
        tmp = $1          #给变量赋新值
        total = $2
}
}
END{    #处理末行,END关键字表示文档读取完毕,
        #理由:最后一次不等时打印的是上次,最后一次没有机会打印
        print $1 " total is : " total
}‘


##备注:这是面试官出的一道题,我想用思路一,结果他说在awk内部实现,我虽有思路但是语法不太记得了,
#而且用手写,结果就惨了


思路1代码:

#!/bin/bash


tmp=`cat test.log |awk ‘{print $1}‘|sort|uniq`    #去重后的值
sum=0
for i in `echo $tmp`        #遍历去重后的值
do
        num=`grep $i test.log|awk ‘{print $2}‘`  #过滤出第一列相等的所有值
        for j in $num          #遍历所有值
        do
                sum=$(($j+$sum))   #相加
        done
echo $i "total is :" $sum    #打印
sum=0    #重新初始化
done

结果:

[[email protected] ~]# sh a.sh 
aaa total is : 1
abc total is : 2
bbb total is : 6
ddd total is : 5
iii total is : 1
sss total is : 1
[[email protected] ~]# sh b.sh 
aaa total is : 1
abc total is : 2
bbb total is : 6
ddd total is : 5
iii total is : 1
sss total is : 1

总结:代码量都差不多,但是明显思路2高级。在awk内部编程,语法不一样,千万注意

1、遍量的定义、使用

2、大括号区分代码块



python 实现:

#!/usr/bin/env python2


con = open("test.log","r")
f1 = []
f2 = []
f3 = []
sum = 0

for lines in con.readlines():
    line = lines.strip().split(" ")
    f1.append(line[0])
    f3.append(line)

f2 = list(set(f1))   #利用集合的特性去重

for n in f2:
    for m in f3:           
        if n == m[0]:
            sum += int(m[1])
    print n + " total is : " + str(sum)
    sum = 0

con.close()


以上是关于编shell脚本遇到一个问题,awk能切割掉最后一个字段的值嘛?的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本里怎么替换掉某个文件的最后一行的最后一个字符

Linux下添加shell脚本使得nginx日志每天定时切割压缩

linux 下写 shell kill掉运行时间超过5分钟的PHP进程

linux 下写 shell kill掉运行时间超过5分钟的PHP进程

awk脚本切割数据库8.0命令结果时出现报错

shell 脚本awk的高级应用之