美文网首页
awk sed grep

awk sed grep

作者: oasis_m | 来源:发表于2020-03-24 14:47 被阅读0次

声明:所有文章只作为学习笔记用,转载非原创

awk 数组经典

http://bbs.chinaunix.net/thread-2312439-1-1.html
https://www.cnblogs.com/pangbing/p/7015745.html

awk 讲解 学习网站

https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
https://www.cnblogs.com/f-ck-need-u/p/

生信技能书 linux 练习题目

https://www.jianshu.com/p/a1bd304b6485
https://www.jianshu.com/p/6f9e10ad4256
或者简写成 awk '{print 1,2}'之类的

基础格式


awk (-F,) 'BEGIN{初始变量}{动作}END{输出结果}‘ 引用文件
#分隔符 介绍
http://blog.chinaunix.net/uid-29529406-id-4808894.html
#运算符号
https://blog.51cto.com/haicang/949060
#printf 
https://www.cnblogs.com/chenjianhong/p/4144293.html

#基础变量
ARGC               命令行参数个数
ARGV               命令行参数排列
ENVIRON            支持队列中系统环境变量的使用
FILENAME           awk浏览的文件名
FNR                浏览文件的记录数
FS                 设置输入域分隔符,等价于命令行 -F选项 默认是空格
NF                 浏览记录的域的个数
NR                 已读的记录数
OFS                输出域分隔符
ORS                输出记录分隔符
RS                 控制记录分隔符 默认是\n

调用方法

1.命令行方式
awk [-F  field-separator]  'commands'  input-file(s)
其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。
在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk

3.将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

课程


例子1. 在一段字符串中,插入e f g 
#  echo "a b c d" | awk '{$2=$2" e f g";print}'
     a b e f g c d
    
#echo "a  b      c        d" | awk '{$2=$2" e f g";print}'
    a b e f g c d 
    提示:abcd 中间有很多空格,经过awk处理后,修改$2会根据OFS重建$0,OFS=" " (默认是空格分隔)-- 修改字段或NF的值导致$0重建的联动效应

例2  
#不规则文件d, 我们想对齐内容
# cat d           
        aaaa          bbb            ccc
   bbb         aaa  ccc
ddd       fff                        eee gg hh ii

awk '{$1=$1; print}' d        #不够整齐
aaaa bbb ccc
bbb aaa ccc
ddd fff eee gg hh ii

# awk 'BEGIN{OFS="\t"}{$1=$1; print}' d  #修改OFS改为\t 制表符号后,整齐
aaaa    bbb     ccc
bbb     aaa     ccc
ddd     fff     eee     gg      hh      ii

提示: 例1、2 都和$0的重建有关

例子3 从ifconfig 命令中 ,删选ip地址的案例

#1. 法一:
ifconfig | awk '/inet / && !($2 ~ /^127/){ print $2}'

#按照段落读取:当某一行后面出现了一个或多个空行
#                           那么空行前面的一部分就是一段
#段落的概念:awk默认按行读取的,
#                       按照段落读取要修改RS
#2. 法二:
ifconfig | awk 'BEGIN{RS=""} NR==1{print}'  #输出第一段
ifconfig | awk 'BEGIN{RS=""} !/lo/ {print $6}'
#3. 法三:
ifconfig | awk 'BEGIN{RS="";FS="\n"} !/lo/ {$0=$2;FS=" ";$0=$0;print $2
}'
     提示 :FS 字段分隔符  RS默认\n    $0=$2  #$0只剩下 

#读取配置文件中的一部分
[mysql]
xxx
xxx
xxx
getline 应用
seq 10 | awk '{getline; print $0}'  # 打印了偶数行 反过来打印奇数行
 https://www.cnblogs.com/zhangray/p/9385138.html 
那么getline究竟是实现什么功能呢?正如getline的翻译,得到行,但是注意,得到的并不是当前行,而是当前行的下一行。以上面的例子来分析,awk首先读取到了第一行,就是1,然后getline,就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF,NR,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。以此类推,就可以得到上面的结果。同样,我们可以利用getline只打印出奇数行。

#去重复
 http://www.letuknowit.com/topics/20120401/use-awk-remove-duplicate-lines.html/ 

数组格式


arr[idx]
arr[idx] = value

awk '{print FNR,$0}' a b
1 a aaaaa
2 b bbbbb
3 c ccccc
4 d ddddd
1 e eeeee
2 f fffff
3 g ggggg

数组
https://www.cnblogs.com/xyt-cathy/p/5478788.html
https://www.lagou.com/lgeduarticle/104184.html 
#遍历数据
for(idx in arr){print arr[idx]}
awk '
    BEGIN{
        arr["one"] = 1
        arr["two"] = 2
        arr["three"] = 3
        arr["four"] = 4
        arr["five"] = 5

        for(i in arr){
            print i " -> " arr[i]
        }
    }
'
#不要随意使用for(i=0;i<length(arr);i++)来遍历数组,因为awk数组是关联数组。但如果已经明确知道数组的所有元素索引都位于某个数值范围内,则可以使用该方式进行遍历。

sed

 https://www.cnblogs.com/tureno/articles/6677942.html  #参数讲解 包含示例
 https://blog.csdn.net/kudou1994/article/details/82804790  #常用

$ sed -n ’2p’/etc/passwd 打印出第2行
$ sed -n ’1,3p’/etc/passwd 打印出第1到第3行
$ sed -n ‘$p’/etc/passwd 打印出最后一行
$ sed -n ‘/user/p’ /etc/passwd 打印出含有user的行
$ sed -n ‘/\$/p’ /etc/passwd 打印出含有$元字符的行,$意为最后一行
$ sed -n ‘$=’ ok.txt    打印总行数

#sed 's///g' 与sed 's///' 的区别
 https://blog.csdn.net/m0_37664906/article/details/78082209 
    ps:  /^ */ 匹配以空格开头的字符
              /^\s/  匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
              /^[[:space:]]*/ 匹配以空格或者是\t制表符开头的字符
         
          +g :匹配每一行有行首到行尾的所有字符
    不加g:匹配每一行的行首开始匹配,匹配到第一个符合的字段,就会结束,跳到下一行


# 
 https://zhidao.baidu.com/question/401518560.html 
grep -v "^\s*#" 和 sed 's/\s*=\s*.*//g' 



#管道以及重定向
-----------------------文件描述符和文件的关系 
先解释下为什么叫重定向这三个字。每个命令/程序运行的时候,默认会打开三个描述符0、1、2,分别用来做标准输入、标准输出、错误输出,在shell下,这3个描述符默认都关联到屏幕上。而在shell中通过>、<这种符号,可以让程序的输入、输出、错误输出改变方向,比如将标准输出输出到一个文件中,而不是写入到默认关联的屏幕中。这就是重定向的解释:改变程序数据的输入、输出方向。

底层原理
 https://www.cnblogs.com/alantu2018/p/8477165.html 
 https://www.cnblogs.com/Jimmy1988/p/7479856.html 

--------------------------

而Linux中万物皆文件,这些文件都可以分配描述符,包括套接字。
程序在打开文件描述符的时候,有三种可能的行为:从描述符中读、向描述符中写、可读也可写。从lsof的FD列可以看出程序打开这个文件是为了从中读数据,还是向其中写数据,亦或是既读又写。例如,tail命令监控文件时,就是打开文件从中读数据的(3r的r是read,w是write,u是read and write)。

# REPLY是'read'命令结果保存的默认变量.

>和<的目标是文件名,表示将数据写入文件或从文件中读取,它的层次是在文件名上改变输入输出的方向。
>&3或5<&6这种,目标是文件描述符,表示改变以某个文件描述符为基准,让另一个文件描述符指向这个基准描述符对应的文件。所以操作层次是在描述符上。

[root@mariadb ~]# lsof -n | grep "/a.sh" | column -t                 
tail  13563  root  3r  REG  8,2  182  69632966  /root/a.sh

- (短横线):表示标准输入,一般用于1个程序需要多个输入的时候。
 https://cloud.tencent.com/developer/article/1036031 
  https://www.jianshu.com/p/f68a6e7ff9b5 
  #cat <<END | diff - <(echo "1 2 3" | tr ' ' '\n')
     > 2
     > 3
     > 4
     > END
# cat命令之前也用过,输出一段文字
# diff是比较2个文件的差异的,需要2个参数
# - (短横线)表示上一个命令的输出,传递给diff
# < 表示其后的命令的输出,也重定向给diff

# 管道符的使用
# 第一个命令的输出作为第二个的输入# 前面的例子中也有使用
# tr: 是用于替换字符的,把空格替换为换行,文字就从一行变为了一列ct
 

相关文章

网友评论

      本文标题:awk sed grep

      本文链接:https://www.haomeiwen.com/subject/llvoyhtx.html