Bash: 使用非字母数字字符作为分隔符将文本文件拆分为单词

10

假设“textfile”包含以下内容:

lorem$ipsum-is9simply the.dummy text%of-printing

假设你想要将每个单词分别打印在一行上。 然而,单词不应该只由空格定义,而是由所有非字母数字字符定义。因此结果应该如下所示:

 lorem
 ipsum  
 is9simply  
 the  
 dummy  
 text  
 of  
 printing

如何使用Bash shell完成此操作?



一些注意事项:

  • 这不是一个作业问题。

  • 当单词仅由空格确定时,较为简单。只需编写以下内容:

  • for i in `cat textfile`; do echo $i; done;
    

    会起到作用,并返回:

     lorem$ipsum-is9simply
     the.dummy
     text%of-printing
    

    我看过一些使用IFS环境变量的解决方案来按非字母数字字符拆分单词(参考下面的链接),但我想避免使用IFS有两个原因:1)它需要(我认为)将IFS设置为长列表的非字母数字字符。2)我觉得它有点丑。

  • 以下是我发现的两个相关问题和答案
    如何在Bash中按分隔符拆分字符串?
    如何在Bash中将行拆分成由一个或多个空格分隔的单词?

2个回答

22
使用 tr 命令:
tr -cs 'a-zA-Z0-9' '\n' <textfile
'-c' 是用于指定字符的补集;'-s' 用于压缩替换中的重复项;'a-zA-Z0-9' 是字母数字字符集(也许还要加上 _ ?);'\n' 是替换字符(换行符)。你还可以使用与本地化相关的字符类(可能包含比上面列表中更多的字符):
tr -cs '[:alnum:]' '\n' <textfile

太完美了,这正是我想要的。谢谢! - Sv1
2
@Sv1:你很可能很快就会拥有很高的声誉。我投票支持你的问题,因为你非常清楚地记录了你想要的内容,并且做了大量的研究。 - grok12
如果你有小数怎么办? - Leyu
1
@Leyu:将额外的字符添加到保留的集合中:tr -cs '[:alnum:]+-.' '\n' < textfile。当然,这将允许通过句点、省略号和虚线等。但它也将允许+1.23和-1.24e-23等内容通过。 - Jonathan Leffler

3
$ awk -f splitter.awk < textfile

$ cat splitter.awk
{
  count0 = split($0, asplit, "[^a-zA-Z0-9]")
  for(i = 1; i <= count0; ++i) { print asplit[i] }
}

谢谢Ross!这很酷,我一直想进入awk世界 :) - Sv1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接