vieyahn2017 / shellv

shell command test and study
4 stars 1 forks source link

9.2 sed用法收集tips-2 #59

Open vieyahn2017 opened 5 years ago

vieyahn2017 commented 5 years ago

sed用法收集tips

vieyahn2017 commented 5 years ago

Vi命令:如何删除全部内容? 在命令模式下,输入:.,$d 一回车就全没了。

:.,$d 

表示从当前行到末行全部删除掉。

用gg表示移动到首行。

vieyahn2017 commented 5 years ago

sed命令实现多行复制 https://blog.51cto.com/ganmu/1913599

参考:

多行文本复制,如何用sed或awk或别的工具实现

有文本

aaa bbb ccc ddd eee 匹配bbb-ddd后复制,变为:

aaa bbb ccc ddd bbb ccc ddd eee 使用命令为:

sed -rn 'p;/bbb/,/ddd/H;/ddd/{g;s/^\n//;p}' file.txt 说明:

sed内部有两个空间,一个模式空间,一个保留空间。

通常sed将文本内容逐行读入模式空间进行处理,保留空间仅用于暂时保留内部数据用于与模式空间的数据交换。可以这么理解:模式空间用于与外部的数据交换,保留空间用于sed内部的数据交换,最终还是要通过模式空间输出。

/bbb/,/ddd/H; 逐行处理时将bbb~ddd区段的文本从sed的模式空间附加到保留空间内,每行内容之间以\n分割,因此,最终保留空间内容为:\nbbb\nccc\nddd

/ddd/{g;s/^\n//;p} 处理到ddd这行后,通过g命令获取保留空间内容到模式空间,通过s替换命令去除开头的\n,p命令打印。

其他回答(此处暂时不理解)

awk '{print $0;}n ~/1/{a=a"\n"$0;}/^bbb/{a=$0;n=1;}/^ddd/{print a;n=0;}' file_name

vieyahn2017 commented 5 years ago

sed每次只替换一行中的第一个命中 https://www.cnblogs.com/wjlv/p/10772888.html

vieyahn2017 commented 5 years ago

Linux:sed删除所有匹配结果中的第一个 https://zhidao.baidu.com/question/431685186216639084.html 测试文件test,内容如下aaahappybbbhappysed-i'0,/happy/{/happy/d}'test之后文件结果变为aaahappybbb请教这里的0,还有后面的大括号都是什么意思呢?没见过这种sed指令的写法,求解... 测试文件test,内容如下

aaa

happy

bbb

happy

sed -i '0,/happy/{/happy/d}' test

之后文件结果变为 aaa

happy

bbb

1、删从0行到happy行 sed -i '0,/happy/d' test.txt 2、删从0行到happy行里面的happy行,相当于删除第一个happy行 sed -i '0,/happy/{/happy/d}' test.txt 3、{}组合命令: 一组命令作为一个块被应用 函数命令之间用";"分割 组合可以嵌套

vieyahn2017 commented 5 years ago

sed系列:行或者模式匹配删除特定行 https://www.cnblogs.com/eustoma/p/5452794.html

vieyahn2017 commented 4 years ago

sed删除匹配行到最后一行 https://www.cnblogs.com/double12gzh/p/10166196.html

[root@dltasoam001jeguan ~]# vi /etc/resolv.conf nameserver 135.111.105.157 nameserver 135.111.105.156 nameserver 135.111.105.155 nameserver 135.111.105.154 ; generated by /usr/sbin/dhclient-script search openstacklocal nameserver 135.111.105.129 nameserver 135.111.105.130

[root@dltasoam001jeguan ~]# sed -i -e '/^;/,$d' /etc/resolv.conf [root@dltasoam001jeguan ~]# cat /etc/resolv.conf nameserver 135.111.105.157 nameserver 135.111.105.156 nameserver 135.111.105.155 nameserver 135.111.105.154

vieyahn2017 commented 4 years ago

sed截取某个区间的内容 https://blog.csdn.net/harukosang/article/details/78131112

l00291777@linux-host-10_67_189_50:~/practice> cat data_passwd.txt
at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
bin:x:1:1:bin:/bin:/bin/bash
daemon:x:2:2:Daemon:/sbin:/bin/bash
dhcpd:x:105:65534:DHCP server daemon:/var/lib/dhcp:/bin/false
ftp:x:40:49:FTP account:/srv/ftp:/bin/bash
games:x:12:100:Games account:/var/games:/bin/bash

1、如果知道行号,可以根据行号来截取

l00291777@linux-host-10_67_189_50:~/practice> sed -n '1,4p' data_passwd.txt
at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash
bin:x:1:1:bin:/bin:/bin/bash
daemon:x:2:2:Daemon:/sbin:/bin/bash
dhcpd:x:105:65534:DHCP server daemon:/var/lib/dhcp:/bin/false

2、如果不知道行号,可以根据正则表达式来截取

l00291777@linux-host-10_67_189_50:~/practice> sed -n '/bin:x:1/,/dhcpd:x:105/p' data_passwd.txt
bin:x:1:1:bin:/bin:/bin/bash
daemon:x:2:2:Daemon:/sbin:/bin/bash
dhcpd:x:105:65534:DHCP server daemon:/var/lib/dhcp:/bin/false
vieyahn2017 commented 4 years ago

sed -n 显示行号中使用变量的问题

http://www.ajaxstu.com/Shellbiancheng/192339.html

这样一个脚本 http://www.ajaxstu.com/Shellbiancheng/192339.html

ls ${path}20160911223*|sort | sed -n ''$t2','$(($t2+50))'p' | while read line do echo $line zcat $line |awk -F '|' '{if ($1~18637105120) print $0}' >> /home/unicomlabs/zhengzhoutime0.txt & done

cat test.txt

123 234 345 542 adb lsnd

我想打印每个文件除了最后两行的数据,脚本如下:

!/bin/sh

line1=wc -l test.txt line2=expr $line1 - 2

sed -n '1,$line2p' test.txt

因为test.txt大小会变,想通过一个变量实现,在sed 显示行号中无法使用变量 好像$line2p看成了一个变量了...

原帖网友的讨论:

fox_fox sed -n '1,'$line2'p' test.txt

这样应该就可以了

r2007 $line2p---->${line2}p 置顶十三问里有说明

cbs20 [quote] sed -n '1,'$line2'p' test.txt [/quote]

可以的,非常谢谢。

[quote] $line2p---->${line2}p [/quote] 好像不行 以下提示: sed: -e expression #1, char 6: Extra characters after command

不好意思,以前看过十三问,没有仔细读 :)

waker 不行是你没看懂什么意思

sed -n 1,${line2}p test.txt

cbs20 sed -n 1,${line2}p test.txt

sed -n '1,${line2}p' test.txt 我给加了引号了~ (不行)

我自己测试

比如显示/etc/hosts,除开最后三行

line=$(($(cat hosts | wc -l) - 3))
sed -n 1,${line}p hosts1            # ok
sed -n '1,'${line}p'' hosts1        # ok
sed -n '1,${line}p' hosts1   # 报错如下
sed: -e expression #1, char 6: extra characters after command
vieyahn2017 commented 4 years ago

在文件开头插入行 sed -i '1 i#! /bin/bash' version_set

vieyahn2017 commented 4 years ago

Linux之sed:删除某行以及替换 https://www.cnblogs.com/fiberhome/p/6898786.html

sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换、删除、新增、选取等特定工作,下面先了解一下sed的用法 sed命令行格式为: sed [-nefri] ‘command’ 输入文本

常用选项: -n∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 -e∶直接在指令列模式上进行 sed 的动作编辑; -f∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作; -r∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法) -i∶直接修改读取的档案内容,而不是由萤幕输出。

常用命令: a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~ c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行! d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚; i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行); p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~ s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

举例:(假设我们有一文件名为ab) 删除某行 [root@localhost ruby] # sed '1d' ab #删除第一行 [root@localhost ruby] # sed '$d' ab #删除最后一行 [root@localhost ruby] # sed '1,2d' ab #删除第一行到第二行 [root@localhost ruby] # sed '2,$d' ab #删除第二行到最后一行

  显示某行 . [root@localhost ruby] # sed -n '1p' ab #显示第一行 [root@localhost ruby] # sed -n '$p' ab #显示最后一行 [root@localhost ruby] # sed -n '1,2p' ab #显示第一行到第二行 [root@localhost ruby] # sed -n '2,$p' ab #显示第二行到最后一行

  使用模式进行查询 [root@localhost ruby] # sed -n '/ruby/p' ab #查询包括关键字ruby所在所有行 [root@localhost ruby] # sed -n '/\$/p' ab #查询包括关键字$所在所有行,使用反斜线\屏蔽特殊含义

  增加一行或多行字符串 [root@localhost ruby]# cat ab Hello! ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1a drink tea' ab #第一行后增加字符串"drink tea" Hello! drink tea ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1,3a drink tea' ab #第一行到第三行后增加字符串"drink tea" Hello! drink tea ruby is me,welcome to my blog. drink tea end drink tea [root@localhost ruby] # sed '1a drink tea\nor coffee' ab #第一行后增加多行,使用换行符\n Hello! drink tea or coffee ruby is me,welcome to my blog. end

  代替一行或多行 [root@localhost ruby] # sed '1c Hi' ab #第一行代替为Hi Hi ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1,2c Hi' ab #第一行到第二行代替为Hi Hi end

  替换一行中的某部分   格式:sed 's/要替换的字符串/新的字符串/g' (要替换的字符串可以用正则表达式) [root@localhost ruby] # sed -n '/ruby/p' ab | sed 's/ruby/bird/g' #替换ruby为bird   [root@localhost ruby] # sed -n '/ruby/p' ab | sed 's/ruby//g' #删除ruby

 插入
 [root@localhost ruby] # sed -i '$a bye' ab         #在文件ab中最后一行直接输入"bye"
 [root@localhost ruby]# cat ab
 Hello!
 ruby is me,welcome to my blog.
 end
 bye

例如:

[asp@BJ-CP-7F-106-36 result]$ cat 11371_mobile_20110425.csv 20110425,北京,北京,13661189983 20110425,北京,北京,15810705979 WAPSJBBI_101> WAPSJBBI_101>spooloff;

[asp@BJ-CP-7F-106-36 result]$ sed -i '/WAPSJBBI_101>/d'11371_mobile_20110425.csv

[asp@BJ-CP-7F-106-36 result]$ cat 11371_mobile_20110425.csv
20110425,北京,北京,13661189983 20110425,北京,北京,15810705979

从结果上看怎么就2行都删了呢? 答案是这样的: sed 后面那个/d是删除的作用,写成sed '/WAPSJBBI_101>/d' 11371_mobile_20110425.csv其实就是在文件11371_mobile_20110425.csv里找到跟 “WAPSJBBI_101>”匹配的行,然后删掉。因为原文中含有“WAPSJBBI_101>”的行是2个,因此就2个一口气都删除了。

删除:d命令 $ sed '2d' example-----删除example文件的第二行。 $ sed '2,$d' example-----删除example文件的第二行到末尾所有行。 $ sed '$d' example-----删除example文件的最后一行。 $ sed '/test/'d example-----删除example文件所有包含test的行。

在看看以前我常写的sed 's/|/,/g' aaa.txt>bbb.txt 这个的意思就是把aaa.txt文件中所有字符串|都换成,这是怎么表示的呢?S代表字符串,g表示行内全面替换。

替换:s命令

$ sed 's/test/mytest/g' example

-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。

$ sed -n 's/^test/mytest/p' example

-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。

$ sed 's/^192.168.0.1/&localhost/' example

-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。

$ sed -n 's/loveable/\1rs/p' example

-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。

$ sed 's#10#100#g' example

-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。

vieyahn2017 commented 4 years ago

sed -n '5,10{/hd/p}' /etc/hosts 显示第五到十行中,包含hd的行

vieyahn2017 commented 4 years ago

sed 指定行范围匹配(转 https://www.cnblogs.com/ai616818/archive/2011/07/06/2099075.html

sed -n '5,10{/pattern/p}' file

sed是一个非交互性性文本编辑器,它编辑文件或标准输入 导出的文件拷贝。标准输入可能是来自键盘、文件重定向、字符串或变量,或者是一个管道文件。sed可以随意编辑小或大的文件,有许多sed命令用来编辑、 删除,并允许做这项工作时不在现场。sed一次性处理所有改变,因而变得很有效,对用户来说,最重要的是节 省了时间。sed必须通过行号和正则表达式指定要改变的文本行 sed怎样读取数据: sed从文件的一个文本行或从标准输入的几种格式中读取数据,将之拷贝到一个编辑缓冲区,然后读命令行或脚本的第一条命令,并使用这些命令查找模式或定位 行号编辑它,重复过程直到命令结束

sed命令的调用: 在命令行键入命令;将sed命令插入脚本文件,然后调用sed;将sed命令插入脚本文件,并使sed脚本可执行 sed [option] sed命令 输入文件 在命令行使用sed命令,实际命令要加单引号 sed [option] -f sed脚本文件 输入文件 使用sed脚本文件 sed脚本文件 [option] 输入文件 第一行具有sed命令解释器的sed脚本文件 option如下: n 不打印; sed不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑),p命令可以用来打印编辑行 c 下一命令是编辑命令,使用多项编辑时加入此选项 f 如果正在调用sed脚本文件,使用此选项,此选项通知sed一个脚本文件支持所用的sed命令,如 sed -f myscript.sed input_file 这里myscript.sed即为支持sed命令的文件 使用重定向文件即可保存sed的输出

使用sed在文本中定位文本的方式: x x为一行号,比如1 x,y 表示行号范围从x到y,如2,5表示从第2行到第5行 /pattern/ 查询包含模式的行,如/disk/或/[a-z]/ /pattern/pattern/ 查询包含两个模式的行,如/disk/disks/ /pattern/,x 在给定行号上查询包含模式的行,如/disk/,3 x,/pattern/ 通过行号和模式查询匹配行,如 3,/disk/ x,y! 查询不包含指定行号x和y的行

基本sed编辑命令: p 打印匹配行 c\ 用新文本替换定位文本 = 显示文件行号 s 使用替换模式替换相应模式 a\ 在定位行号后附加新文本信息 r 从另一个文本中读文本 i\ 在定位行号后插入新文本信息 w 写文本到一个文件 d 删除定位行 q 第一个模式匹配完成后退出或立即退出 l 显示与八进制ASCII代码等价的控制字符 y 传送字符 n 从另一个文本中读文本下一行,并附加在下一行 {} 在定位行执行的命令组 g 将模式2粘贴到/pattern n/

基本sed编程举例: 使用p(rint)显示行: sed -n '2p' temp.txt 只显示第2行,使用选项n 打印范围: sed -n '1,3p' temp.txt 打印第1行到第3行 打印模式: sed -n '/movie/'p temp.txt 打印含movie的行 使 用模式和行号查询: sed -n '3,/movie/'p temp.txt 只在第3行查找movie并打印 显示整个文件: sed -n '1,$'p temp.txt $为最后一行 任意字符: sed -n '/.ing/'p temp.txt 注意是.ing,而不是*ing 打印行号: sed -e '/music/=' temp.txt 附加文本:(创建sed脚本文件)chmod u+x script.sed,运行时./script.sed temp.txt

!/bin/sed -f

/name1/ a\ #a\表示此处换行添加文本 HERE ADD NEW LINE. #添加的文本内容 插入文本: /name1/ a\ 改成 4 i\ 4表示行号,i插入 修改文本: /name1/ a\ 改 成 /name1/ c\ 将修改整行,c修改 删除文本: sed '1d' temp.txt 或者 sed '1,4d' temp.txt 替 换文本: sed 's/source/OKSTR/' temp.txt 将source替换成OKSTR sed 's/\$//g' temp.txt 将文本中所有的$符号全部删除 sed 's/source/OKSTR/w temp2.txt' temp.txt 将替换后的记录写入文件temp2.txt 替换修改字符串: sed 's/source/"ADD BEFORE" &/p' temp.txt 结果将在source字符串前面加上"ADD BEFORE",这里的&表示找到的source字符并保存 sed结果写入到文件: sed '1,2 w temp2.txt' temp.txt sed '/name/ w temp2.txt' temp.txt 从文件中读文本: sed '/name/r temp2.txt' temp.txt 在每列最后加文本: sed 's/[0-9]*/& Pass/g' temp.txt 从 shell向sed传值: echo $NAME | sed "s/go/$REP/g" 注意需要使用双引号

快速一行命令: 's/.$//g' 删除以句点结尾行 '-e /abcd/d' 删除包含abcd的行 's/[][][]/[]/g' 删除一个以上空格,用一个空格代替 's/^[][]//g' 删除行首空格 's/.[][]*/[]/g' 删除句号后跟两个或更多的空格,用一个空格代替 '/^$/d' 删除空行 's/^.//g' 删除第一个字符,区别 's/.//g'删除所有的句点 's/COL/(...)//g' 删除紧跟COL的后三个字母 's/^\///g' 删除路径中第一个\

sed '1{:a;N;6!ba};N;${P;Q};D' awk '{a[NR%7]=$0}END{print a[(NR-6)%7]}'

从性能上来讲,倒数几行的问题,还是用tail的好 tail -7 | head -1

vieyahn2017 commented 3 years ago

Linux之使用sed取出IP地址


//匹配IP地址
ip addr|sed -nr 's#^.*inet (.*)/24.*$#\1#gp'
ip addr|awk -F '[ /]+' 'NR==9 {print $3}'
//对调用户名,登录权限
cat /etc/passwd|sed -nr 's#([^:]+)(:.*:)(/.*)#\3\2\1#gp'
vieyahn2017 commented 3 years ago

获取 ETCD_ENDPOINTS

ps -ef | grep xxxxxxxxx
paas        402      1  0 Nov26 ?        00:18:05 /xxxxxxxxxx --hostname-override node-1 -LogOutput /xxxxxxx/controller.log --log-format=utc -SelfStoreEndpoint 172.17.37.30:20101 --storage-backend=etcd3  ***more***
#从中获取172.17.37.30:20101
endpoints=$(ps -ef|grep xxxxxxxxx |sed -nr 's#^.*SelfStoreEndpoint (.*) --storage.*$#\1#gp')

# etcd登录
ETCD_ENDPOINTS=https://192.168.132.2:2379
etcdctl --endpoints=${ETCD_ENDPOINTS} get / --prefix --keys-only