≡菜单

Unix Sed教程:高级Sed替换示例

Linux Sed示例-高级查找和替换操作本文是正在进行的一部分 Unix Sed技巧和窍门 系列。

In our previous sedarticles we learned — sedprinting, seddeletion, sedsubstitute , sedfile writesedmultiple commands.

在本文中,让我们回顾一下一些有趣的变通方法。“s”sed命令中有几个实际示例。

I. Sed替代分隔符

正如我们在上一篇文章中讨论的那样,我们可以使用不同的定界符,例如@%|。 ; :在sed替代命令中。

让我们首先创建path.txt文件,该文件将在下面提到的所有示例中使用。

$ cat path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

例子1–sed @分隔符:将/ opt / omni / lbin替换为/ opt / tools / bin

当您替换具有以下内容的路径名时‘/’,您可以使用@作为分隔符,而不是‘/’。在下面的sed示例中,在输入文件的最后一行中,/ opt / omni / lbin更改为/ opt / tools / bin。

$ sed'[email protected]/opt/omni/[email protected]/opt/tools/[email protected]' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

例子2–sed /分隔符:将/ opt / omni / lbin替换为/ opt / tools / bin

什么时候应该使用‘/’在与路径名相关的替换中,您必须转义‘/’如下所示。在此sed示例中,定界符‘/’在REGEXP和REPLACEMENT部分中转义了。

$ sed's / \ / opt \ / omni \ / lbin / \ / opt \ / tools \ / bin / g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

二。塞德‘&’ Get Matched String

正则表达式匹配的输入行的精确部分由&,然后可以在替换零件中使用它。

例子1– sed&用法:将/ usr / bin /替换为/ usr / bin / local

$ sed'[email protected]/usr/[email protected]&/[email protected]' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin/local:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin/local:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

在上面的例子中‘&’在替换部分中,将使用匹配的模式替换/ usr / bin,并使用/ local添加它。因此,在输出中,所有/ usr / bin的出现都将替换为/ usr / bin / local

例子2– sed&用法:匹配整行

&用给定的REGEXP替换任何匹配项。

$ sed'[email protected]^.*[email protected]<<<&>>>@g' path.txt
<<</usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin>>>
<<</usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:>>>
<<</opt/omni/lbin:/opt/omni/sbin:/root/bin>>>

在上面的例子中regexp has “^.*$”匹配整行更换部件<<<&>>>用写全行<<< and >>>在行的开头和结尾处。

三, Sed中的分组和反向引用

可以像正常正则表达式一样在sed中使用分组。打开一个组“\(” and closed with “\)”。分组可以与反向引用结合使用。

向后引用是重用通过分组选择的正则表达式的一部分。 sed中的反向引用可以在正则表达式和替代命令的替换部分中使用。

示例1:仅获得每行中的第一个路径

$ sed's/\(\/[^:]*\).*/\1/g' path.txt
/usr/kbos/bin
/usr/local/sbin
/opt/omni/lbin

在上面的示例中,\(\ / [^:] * \)匹配first:出现之前的可用路径。 \ 1替换第一个匹配的组。

示例2:多重分组

在文件path.txt中,更改文件最后一行中字段的顺序。

$ sed'[email protected]\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\[email protected]' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/omni/bin:
/root/bin:/opt/omni/sbin:/opt/omni/lbin

在上面的命令中$指定仅对最后一行进行替换。输出显示最后一行中的路径值顺序已颠倒。

示例3:在/ etc / passwd文件中获取用户名列表

这个sed示例仅显示/ etc / passwd文件中的第一个字段。

$ sed's/\([^:]*\).*/\1/' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown

范例4:在每个字词的第一个字元加上括号

这个sed示例在括号中显示了每个单词的第一个字符。

$回声"欢迎来到极客的东西"| sed's/\(\b[A-Z]\)/\(\1\)/g'
(W)elcome (T)o (T)he (G)eek (S)tuff

示例5:传达简单数字。

让我们创建一个名为数字的文件,其中包含数字列表。下面的sed命令示例用于将数字相乘直到成千上万。

$ cat 数字
1234
12121
3434
123

$sed 's / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2,\ 3 / G' numbers
1,234
12,121
3,434
123

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101 Hacks书 Sed和Awk 101黑客手册 Nagios Core 3书 Vim 101黑客手册

{ 41 评论… 加一 }

  • 浆果 2009年11月2日,晚上11:23

    亲爱的作者,
    在示例4中,\ b转义字符是什么意思?为什么REGEXP可以完成任务?

  • 萨西卡拉 2009年11月3日,上午5:31

    @浆果,

    \ b匹配单词边界。

    如果在示例4中省略\ b,则只需在所有大写字母中加上括号。

    $回声“欢迎来到极客的东西” | sed‘s/\([A-Z]\)/\(\1\)/g’
    (W)欢迎(T)o(T)他(G)周(S)凝灰岩(P)ost

  • 浆果 2009年11月7日,上午1:38

    @Sasikala,

    哦,我明白了。非常感谢你。 ^ _ ^

    Following your tips, I found that /可以匹配的权利。再次感谢你!

  • 浆果 2009年11月7日,上午1:41

    @Sasikala,

    按照您的提示,我发现/“smaller than”可以匹配左边界和/加“larger than”可以匹配的权利。再次感谢你!

  • 大师普拉萨德 2010年2月27日,上午1:37

    你好
    关于示例4,当我在Red Hat linux中尝试时,它可以工作,但是当我在HP-UX或SunOS中尝试时,它却不能。有什么理由吗?

  • 大师普拉萨德 2010年2月27日,上午1:40

    此外,示例5也是如此…请让我知道为什么

  • 安朱姆 2010年4月9日,上午11:17

    示例5可能仅适用于Linux(我不’(请参阅方法),但不适用于其他系统。以下代码段可在Sun OS上运行,并且肯定可以在大多数系统上运行。包括Linux:

    回声‘1234
    12121
    3434
    123’ | sed‘s / \([0-9] \ {3 \} \)$ /,\ 1 / g; s / ^,//’

    谢谢,
    -安菊

  • 安朱姆 2010年4月9日,下午4:10

    示例4在Solaris 9上进行了重新设计和测试:

    回声“欢迎来到极客的东西” | sed‘s/\<\([A-Z]\)/\(\1\)/g'

    谢谢,
    -安菊

  • 洛根 2010年8月10日,下午4:35

    commify的完整示例(将逗号添加为千位分隔符)

    $ catnumbers.txt
    1
    12
    123
    1234
    12345
    123456
    1234567
    12345678
    123456789
    1234567890
    1234567890.1234
    +1234567890.1234
    -1234567890.1234

    随着“-r”选项,则无需转义和大括号。

    下面的简单代码没有’t适用于大于6的数字字符串。

    $ sed-r‘s /(^ | [^ 0-9。])([0-9] +)([0-9] {3})/ \ 1 \ 2,\ 3 / g’ numbers.txt
    1
    12
    123
    1,234
    12,345
    123,456
    1234,567
    12345,678
    123456,789
    1234567,890
    1234567,890.1234
    +1234567,890.1234
    -1234567,890.1234

    这个作品。 (摘自第4.14题, http://sed.sourceforge.net/sedfaq.html)
    $ sed-r‘:a; s /(^ | [^ 0-9。])([0-9] +)([0-9] {3})/ \ 1 \ 2,\ 3 / g; ta’ numbers.txt
    1
    12
    123
    1,234
    12,345
    123,456
    1,234,567
    12,345,678
    123,456,789
    1,234,567,890
    1,234,567,890.1234
    +1,234,567,890.1234
    -1,234,567,890.1234

  • 匿名 2010年12月1日,上午7:32

    您能解释一下这个替换吗?
    sed-r ‘s /(^ | [^ 0-9。])([0-9] +)([0-9] {3})/ \ 1 \ 2,\ 3 / g’ numbers.txt

    谢谢,
    拉菲

  • 西瓦 2011年11月14日,上午12:59

    我不清楚。您能否在Sed中解释此分组和反向引用。

    提前致谢。

  • 巴拉提 2012年3月7日,上午12:08


    您能否使用sed命令在压延机中给出一个用日历中的*或**(*表示两位,**两位)替换当前日期的示例。
    谢谢

  • 匿名 2012年4月28日,上午2:32

    你能告诉我这是什么吗“^” actually does ??

  • 鲍比 2012年5月9日,上午8:02

    ‘^’有两个目的。在[]内表示“not these”,但除此之外“the start of input”. So, for example

    回声“why 你好” | sed‘s/hello/goodbye’
    将取代‘hello’ with ‘goodbye’, but

    回声“why 你好” | sed‘s/^hello/goodbye’
    不会取代‘hello’ with ‘goodbye’因为它不在输入的开头。

    回声“why 你好” | sed‘s/[^z]ello/goodbye’
    Would replace 你好 with 再见 (because ‘hello’不以‘z’)

  • 菲尼 2012年6月18日,上午4:25

    嗨,
    使用Sed可以在不打扰旧条目的情况下在crontab文件中追加/删除新内容。

  • 射线 2012年7月11日,上午7:24

    我正在尝试解析头文件和数组大小并稍后粘贴。
    我想更改如下行:
    bool SetValues(int array1[30], int array2[30, 整数大小)
    我希望它看起来像
    SetValues(&array1[0], &array2[0], 30).
    我有很多,但我不知道如何替换字符串:”int size”
    与字符串“30”
    我无法弄清楚如何保留我想要的模式,以后再用它代替。

  • Upalshah 2012年8月25日,上午5:42

    名称标记等级
    abc 50 CB
    定义45 CC
    ghhi 55 CA
    jkl 85 A
    mno 75 BA
    pqr 77 BA
    斯图89 A

    我的问题是..
    在标记列中的每个标记值后添加.00…
    how can I do with sedcommand??????
    还有其他命令吗???

  • 理查德·M 2012年8月29日,上午7:07

    $ cat file.txt
    名称标记等级
    abc 50 CB
    定义45 CC
    ghhi 55 CA
    jkl 85 A
    mno 75 BA
    pqr 77 BA
    斯图89 A
    $ cat file.txt | awk‘{print $1, $2″.00″, $3}’
    名称标记.00级
    abc 50.00 CB
    定义45.00 CC
    ghhi 55.00 CA
    jkl 85.00 A
    mno 75.00 BA
    pqr 77.00 BA
    斯图89.00 A
    $

  • 约翰 2012年11月28日,下午12:31

    你好
    我想在文件的每一行的特定位置插入空字符。
    我怎样才能做到这一点?
    提前致谢。

  • 匿名 2013年2月4日,上午7:21

    你好
    如何在不触摸行中其他条目的情况下将/ etc / shadow文件的第二个字段更改为NP

  • 纳吉 2013年2月22日,上午1:50

    谢谢thegeekstuff.com每次给我们有趣的信息

  • dude4linux 2013年2月23日,上午11:32

    我使用以下sed命令向.bashrc添加一些其他别名
    sed-i -e ‘/ls –color=auto/a \
    别名ll =”ls –color=auto -lh” \
    别名la =”ls –color=auto -lAh” \
    别名l =”ls –color=auto -CF”
    ‘ ~/.bashrc
    我想使用单引号‘出于美观原因,在添加的行中添加了所有代码,但是所有转义代码组合都不适合我。一世’ve tried \’, ”, ”’,甚至尝试交换‘ and “。知道如何在添加的行中包含单引号吗?

  • 优素福 2013年4月3日,上午1:33

    你好
    您能否解释一下示例5,它是如何工作的。

    $ sed‘s / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2,\ 3 / G’ numbers

  • 优素福 2013年4月3日,晚上11:09

    老板,请解释示例5。

  • 苏德山 2013年4月15日,上午4:49

    任何人都请告诉我,如何使用sed命令在Linux文件中的第10行之后添加以下信息

    ============================================== =================
    启用S​​SLEngine
    JkMountCopy开
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4 + RSA:+ HIGH:+ MEDIUM:+ LOW:+ SSLv2:+ EXP:+ eNULL

    SSLCertificateFile“/opt/test/sys/Apache/conf/ssl.crt/server.crt”
    SSLCertificateKeyFile“/opt/test/sys/Apache/conf/ssl.key/server.key”

    SSLOptions + StdEnvVars

    SSLOptions + StdEnvVars

    自定义日志“/opt/test/sys/Apache/logs/ssl_request.log” “%t%h%{SSL_PROTOCOL} x%{SSL_CIPHER} x \”%r\” %b”

    ============================================== =================

  • 洛根·帕拉尼萨米(Logan Palanisamy) 2013年4月15日,上午10:21

    这是你做的。

    1.将要插入的内容在第10行之后保存到单独的文件中。
    2.使用读取选项(“r”)将上述文件读入原始文件。

    原始文件
    $猫myfile.txt
    这是第一行
    这是第二行
    这是第3行
    这是第4行
    这是第5行
    这是第6行
    这是第7行
    这是第8行
    这是第9行
    这是第10行
    这是第11行
    这是第12行

    保存要插入到new_file.txt中的内容
    $ cat new_file.txt
    =======================
    新线1
    新线2
    新线3
    新线4
    新线5
    =======================

    将new_file的内容读入原始文件myfile.txt
    $ sed’10r new_file.txt’ myfile.txt
    这是第一行
    这是第二行
    这是第3行
    这是第4行
    这是第5行
    这是第6行
    这是第7行
    这是第8行
    这是第9行
    这是第10行
    =======================
    新线1
    新线2
    新线3
    新线4
    新线5
    =======================
    这是第11行
    这是第12行

  • 苏德山 2013年4月16日,上午12:25

    非常感谢Logan Palanisamy ,,,,再次非常感谢palanisamy…!!非常有效,非常感谢…!!

  • 苏德山 2013年4月16日,上午12:33

    洛根·帕拉尼萨米(Logan Palanisamy),但是在文本中,当我在文本中放置命令sed -i时,我必须传递$ HOSTNAME $ PWD之类的变量’10r text’httpd.conf,它照原样保存,但未取代$ HOSTNAME和$ PWD的值,请在这方面帮助我logan palanisamy

    #ServerAdmin [email protected]
    #DocumentRoot /www/docs/dummy-host.example.com
    服务器名称$ HOSTNAME
    #ErrorLog日志/dummy-host.example.com-error_log
    # 自定义日志logs/dummy-host.example.com-access_log common
    启用S​​SLEngine
    JkMountCopy开
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4 + RSA:+ HIGH:+ MEDIUM:+ LOW:+ SSLv2:+ EXP:+ eNULL

  • 库沙尔 2013年6月12日,上午5:58

    有人可以解释示例1的每个字段的含义吗?

  • 伊森 2013年9月11日,上午8:32

    嗨,作者,

    关于第三节中的示例1,我有一条评论。 Sed中的分组和反向引用)。

    你写了,“\(\ / [^:] * \)匹配first:出现之前可用的路径。”,这是不正确的。

    说明:

    让’s get rid of “\(” and “\)”在表达式中,用于分组。

    对于其余部分,“\/[^:]*”,表示匹配以开头的字符串“/”,然后是除“:”,连续零次或多次。

    因此,您的解释应更正为“\(\ / [^:] * \)匹配任何不包含冒号的路径。”

    该行中路径的第一次出现用“\1”, not “\(\/[^:]*\)”.

  • 普拉萨德 2013年11月12日,上午6:04

    请帮我
    我有一个文本文件。
    猫sample.txt
    0
    0
    0
    0
    0
    0
    i want to replace 0 with name using sedcommand

  • 普拉萨德 2013年11月12日,上午7:43

    请帮我…for this also

    我有一个500电话号码的文件..我想用name = data替换号码。
    using sedcommand .

  • J 2013年11月22日,下午12:19

    @sasikala
    首先,我想说的是,对于那些热衷于学习的人来说,您的例子不仅仅在sed上是一个绝佳的起点

    我的问题是示例5

    ———————————————————————
    $ sed‘s / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2,\ 3 / G’ numbers
    ———————————————————————

    你能告诉我点是什么“.”模式\(^ \ | [^ 0-9。] \)中的9之后呢?
    该模式应匹配所有不是开头处固定的数字的字符,并以此定义第一个组。

    但是即使在9之后没有点也可以使用。你能解释一下9点后的点是什么吗?

  • 巴什瓦尔 2014年10月13日,上午4:34

    如果我们这样做,输出是什么?

    回声“something” | sed-e ‘s / searched_string_name //’

  • 谢尔盖 2014年11月19日,上午5:54

    避免类似\ / \ / \ / \ / \ / \ / \ / \ / \ //的类似栅栏的构造的好方法:使用冒号作为分隔符
    sed‘s:old:new:g’
    这条路
    sed‘s / \ / opt \ / omni \ / lbin / \ / opt \ / tools \ / bin / g’ path.txt
    变成
    sed‘s:/ opt / omni / lbin:/ opt / tools / bin:g’ path.txt
    这更容易阅读!

  • 塞尔希 2015年3月11日,上午8:38

    sed‘s/[:].*/ /g’ /etc/passwd
    最好的例子

  • 纳雷什 2015年5月5日,晚上11:04

    如何转义(反引号)字符或将`替换为‘ ( single quotes ) .

    例如:Sampl`e

    谢谢

  • 史蒂夫 2015年10月15日,上午5:05

    示例3更简单:
    sed‘s/:.*//’ /etc/passwd

  • 史蒂夫 2015年10月15日,上午5:08

    “但是即使在9之后没有点也可以使用。你能解释一下9点后的点是什么吗?”

    []将所有允许的字符括在一个字符位置,因此[0-9。]将匹配数字字符或句点。在[]之外使用的句点与其中的任何字符匹配’s treated literally.

  • 拉马夫塔尔 2016年2月24日,晚上10:22

    你好先生
    您的示例非常适合学习。
    您能否解释一下它是如何工作的。这是此页面上给出的最后一个示例。
    $ sed‘s / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2,\ 3 / G’ numbers
    1,234
    12,121
    3,434
    123

  • 丰富 2016年6月5日,上午7:25

    拉马夫塔尔:

    $ sed的s / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2, \ 3 / g'数字

    (1)\(^ \ | [^ 0-9。] \)–匹配任何前导(^)空OR | [^ x]非数字而非句号
    (2)\([0-9] \ + \)–仅匹配一个或多个数字
    (3)\([0-9] \ {3 \} \)–匹配一组3个数字
    / g全线

    \ 1 \ 2和\ 3对应于组#’s above
    如上所述,需要:a和; ta来获取所有数字
    sed‘:a;s / \(^ \ | [^ 0-9。] \)\([0-9] \ + \)\([0-9] \ {3 \} \)/ \ 1 \ 2,\ 3 / G;ta’

    这会创建一阵不行的循环
    :a创建标签
    ;如果分支成功,则返回(t)到label(a)。

发表评论