AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 723659
Accepted
Ray Andrews
Ray Andrews
Asked: 2022-11-05 06:15:31 +0800 CST2022-11-05 06:15:31 +0800 CST 2022-11-05 06:15:31 +0800 CST

使用“sed”替换任何单词,而不是字符

  • 772

我知道如何使用sedwith[^xxxx]语法来排除字符,但是如何排除一个词呢?例如我的变量:

var="
Now is the time
for all good men 
to come 
to the aid  
of the party" 

现在:

echo $var | sed ...

...我想结束:

REPLACED time
for all good men 
to come 
REPLACED aid  
REPLACED party 

...这应该很简单,但我不知道该怎么做。

echo $var | sed -r 's/^[^the]*the/REPLACED/'

...有点接近,但t h e匹配为单个字符,而不是单词the。

如果有解决方案,我可以将所有内容替换为多次出现的第一个,甚至可以替换为特定的出现,那会更好。

text-processing
  • 3 3 个回答
  • 259 Views

3 个回答

  • Voted
  1. AdminBee
    2022-11-05T06:21:23+08:002022-11-05T06:21:23+08:00

    您可以按如下方式实现,假设the线上最多有一个实例:

     sed -E 's/.*\Wthe(\W.*)/REPLACED\1/'
    

    the这将用您的替换文本替换直到最后一次出现的所有内容(请记住,正则表达式是贪婪的) 。

    • 它通过存储最后一次出现之后的所有内容来做到这一点,并the用非单词字符括起来(以防止部分单词匹配,例如),包括在捕获组中以 ,theoretical结尾的非单词字符。the( ... )
    • 然后它将用替换文本替换该行,然后是捕获组的内容(之所以称为 是\1因为它是搜索模式中的第一个这样的组)。这种有点复杂的方法是必要的,以便终止的字符the也被转移到替换文本中。

    如果您想替换第一次出现的所有内容,您可能不得不求助于awk:

    awk '(i=match($0,/\Wthe\W/)){print "REPLACED" substr($0,i+4);next} 1'
    

    这将检查the被非单词字符包围的字符串是否出现在行中,并将位置存储在变量i中。

    • 如果i非零,它将在出现之后打印替换文本和当前输入行的子字符串the,否则跳过执行到下一行。
    • 如果i为零,它只是按原样打印当前行。
    • 5
  2. Best Answer
    Stéphane Chazelas
    2022-11-05T08:30:13+08:002022-11-05T08:30:13+08:00

    s/.*the/REPLACED/替换直到最右边出现的所有内容,the因为它.*很贪婪并且希望尽可能多地匹配。

    .*是 0 个或多个 ( *) 个字符 ( .)尽可能多,并且会愉快地吞噬所有出现的the不包括最后一个需要与正the则表达式的以下部分匹配的字符。

    大约 30 年前,perl5 引入了*:的变体*?,它也匹配 0 个或多个前面的事物,但尽可能少:

    printf '%s\n' "$var" | perl -pe 's/.*?the/REPLACED/'
    

    很少有人sed添加了对这些新perl运算符的支持。我只知道两种实现方式(ssedwith-R和 ast-open 的 with -E/ -A/ -X/ -P)。在其他seds 中,?与文字匹配?或与-E/匹配-r,*?要么是错误,要么与*理解为*运算符(0 或更多)与?(0 或 1)组合相同。

    对于sed不支持的实现*?,当要替换的是单个字符(如x)时,您s/[^x]*x/REPLACE/可以说 0 或更多(*)字符而不是x([^x]),尽可能多,并且因为我们排除x了 ,它将存储在第一个之前x发生。

    你不能将它用于超过一个字符的字符串,因为你不能尽可能多地说 0 个或多个字符,只要不包括 "the"。所以你需要一种不同的方法。

    s/the/REPLACEMENT/替换第一次出现的the,因此标准sed中替换所有字符直到第一次出现的字符串的常用方法是用换行符替换它(否则保证该字符不会出现在模式空间中),然后替换该换行符之前的所有内容:

    sed 's/the/\
    /;s/.*\n//'
    
    • 4
  3. Marius_Couet
    2022-11-05T06:59:01+08:002022-11-05T06:59:01+08:00

    如果您需要将所有内容替换为第一个the,您可能需要非贪婪量词,而基本正则表达式和扩展正则表达式都无法识别这些量词。

    在那种情况下,如果sed对你来说不是强制性的,你可以使用perl:

    perl -pe 's/.*?\Wthe/REPLACED/'
    

    如果您需要替换最多n出现次数(替换n为您的出现次数):

    perl -pe 's/(.*?\Wthe){1,n}/REPLACED/'
    
    • 2

相关问题

  • grep 从 $START 到 $END 的一组行并且在 $MIDDLE 中包含匹配项

  • 重新排列字母并比较两个单词

  • 在awk中的两行之间减去相同的列

  • 多行文件洗牌

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve