“sed”与模式不匹配
Posted
技术标签:
【中文标题】“sed”与模式不匹配【英文标题】:"sed" doesn't match pattern 【发布时间】:2021-05-23 02:18:08 【问题描述】:我正在尝试格式化剪切、粘贴输出,但 sed 不起作用。
文件.txt
Apple
Banana
Apple
Banana
Orange
Apple
Orange
code.sh
cut -f2 file.txt | sort | uniq | sed 's/^\|$/#/g'| paste -sd,\& -
ubuntu 上的预期输出/输出
#Apple#,#Banana#&#Orange#
在 macOS 上获取输出/输出
Apple,Banana&Orange
注意:代码可在 Ubuntu 上运行,但在 MacOS 上则不行。
【问题讨论】:
仅供参考,您可以将sort | uniq
组合到 sort -u
macos sed 可能不支持\|
.. 你可以试试sed -E 's/^|$/#/g'
另见:***.com/questions/24275070/…
此问题与cut
、sort
、uniq
、paste
无关。您可以将整个示例简化为 echo foo | sed 's/^\|$/#/g'
@Sundeep 很奇怪,在每行的开头插入#
,而不是结尾。
为什么是cut -f2
?该文件只有一个字段。
【参考方案1】:
这可以在单个gnu-awk
中完成:
awk '!seen[$1]++ END
PROCINFO["sorted_in"]="@ind_str_asc"
for (i in seen)
s = s (s == "" ? "" : (++j==1?",":"&")) "#" i "#"
print s
' file
#Apple#,#Banana#&#Orange#
在 OSX 上,我通过 home brew
安装了 gnu awk
。
【讨论】:
看起来不错,我有自制的,但我不使用 awk。 安装超级简单然后brew install gawk
【参考方案2】:
正如在别处提到的,BSD sed
不支持 \|
。除了替换^
和$
,您可以替换#
围绕整行。
sort -u file.txt | sed 's/.*/#&#/' | paste -sd,'&' -
【讨论】:
感谢sort -u
,但它适用于 ubuntu 吗?
它应该适用于任何地方,它是标准的sort
选项,早于所有不同风格的 Unix。
我意识到您的解决方案工作正常,但请告诉我一件事,为什么您在 s/.*/#&#/
中将 $
替换为 &
。使用 $
不起作用。
&
被替换为任何匹配的正则表达式,即整行。
对,-u
是 POSIX sort
的必需参数,请参阅 pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html,并且在我记得过去 40 多年中使用的所有类型中都存在。【参考方案3】:
据我所知,BSD/Mac sed
不支持 \|
。详情请见sed not giving me correct substitute operation for newline with Mac - differences between GNU sed and BSD / OSX sed。
作为替代方案,您可以使用 ERE 代替 BRE。我在 Linux 上检查过,显然这在 Mac 上似乎仍然不起作用(另见:MacOS sed: match either beginning or end)。
$ echo 'Apple' | sed -E 's/^|$/#/g'
#Apple#
# workaround for Mac
$ echo 'Apple' | sed -e 's/^/#/' -e 's/$/#/'
#Apple#
除了sort+uniq+sed
,您还可以使用awk
(但请注意,此处显示的awk
解决方案会在保留原始顺序的同时删除重复项,而不是sort
输入):
$ awk '!seen[$0]++print "#" $0 "#"' ip.txt
#Apple#
#Banana#
#Orange#
如果您只需要第二个字段,请将$0
更改为$2
,具体取决于您对cut
的使用
【讨论】:
可能取决于操作系统版本,但在 10.13.6 上,sed
命令仅生成 #Apple
@Barmar 我只有 Linux,所以无法在其他地方进行测试。编辑答案以反映这一点。
Sundeep 和 @Barmar - 请参阅 superuser.com/a/1420167,您遇到了 MacOS 上 sed 中的 s/^|$/#/g
错误。
好找到@EdMorton
@Barmar,谢谢。我敢肯定还有其他提供 C&V 的帖子,因为我以前遇到过这个,我只是懒得去寻找它们!【参考方案4】:
使用 sed 命令的简单方法:
sed -E 's/[[:alnum:]]+/#&#/'
用于启用 POSIX ERE 的 -E 选项(扩展常规
表达)
[[:alnum:]]+ 字母数字字符;在 ASCII 中,相当于 [A-Za-z0-9] 加上加号 (+) 表示一个或多个。
& 符号确实带来或引用了我们发现的模式的内容。 (我们用#包围它)
【讨论】:
以上是关于“sed”与模式不匹配的主要内容,如果未能解决你的问题,请参考以下文章