我在网上找到了一段代码,它实际上有助于创建文本文件中每个单词的频率,但是我希望有人准确解释它是如何做到的
特别是 sed 命令,因为我对 bash 非常陌生,我需要知道所有分隔符正在做什么(s/\(.*\)/\L\1/
)。
这是代码:
cat EnglishText.txt
sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g' EnglishText.txt | sort | uniq -c
我想知道 sed 之后到底发生了什么,我确实理解 uniq -c 和排序,但我想知道匹配中发生了什么等等..我知道这有点奇怪,但我再次感到非常对此不熟悉
在同一问题的上下文中
sed 's/\([0-9]*\).*/\1/'
这意味着什么?
答案1
该sed
脚本由三个替代命令组成。替换命令的形式是s/old/new/
在文本中查找与正则表达式匹配的内容old
并将其替换为new
。如果 ag
放在命令后面,则重复执行此替换(“全局”)。第一个删除句点。第二个使文本小写。第三个将每个单词放在自己的行上。更详细地说:
s/\.//g
这会匹配输入中的句点并将其替换为空。
s/\(.*\)/\L\1/
这会匹配输入中的任何内容,并将其替换为相同内容的小写版本。
s/\ /\n/g
这会用换行符替换空格。这具有将每个单词放在单独的行上的效果。
例子
请注意,句点被删除,所有单词都小写并放在单独的行上:
$ echo 'This test is this test.' | sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g'
this
test
is
this
test
这种形式适合排序和计数:
$ echo 'This test is this test.' | sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g' | sort | uniq -c
1 is
2 test
2 this
改进
正如所写的,该sed
脚本不会对其他标点符号(例如?"!
、 或制表符)执行任何操作。对上述代码稍作修改,即可处理所有问题:
$ echo 'This "test(?)" is this test!' | sed 's/[[:punct:]]//g; s/.*/\L&/; s/[[:space:]]/\n/g' | sort | uniq -c
1 is
2 test
2 this
这使用与原始命令相同类型的替代命令,仅进行了一些小的更改:
s/[[:punct:]]//g
删除所有标点符号。s/.*/\L&/
将所有大写字符转换为小写。s/[[:space:]]/\n/g
用换行符替换所有空格。
附录
如果一行以数字开头,则sed 's/\([0-9]*\).*/\1/'
保留该数字并删除其后的所有内容。所有其他行都被删除。例如:
$ echo '123 tests' | sed 's/\([0-9]*\).*/\1/'
123
$ echo 'There are 123 tests' | sed 's/\([0-9]*\).*/\1/'