shell脚本中sed的解释

Jav*_*eak 1 shell sed

我在网上找到了一段代码,它实际上有助于在文本文件中创建每个单词的频率,但是我希望有人确切地解释它是如何做到的

特别是 sed 命令,因为我是 bash 的超级新手,我需要知道所有分隔符都在做什么 ( s/\(.*\)/\L\1/)。

这是代码:

cat EnglishText.txt
sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g' EnglishText.txt | sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

我想知道 sed 之后到底是什么,我确实了解 uniq -c 和排序,但我想知道匹配中发生了什么等等..我知道这有点奇怪,但我再次非常新来的

在同一问题的上下文中

sed  's/\([0-9]*\).*/\1/'
Run Code Online (Sandbox Code Playgroud)

这意味着什么?

Joh*_*024 5

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
Run Code Online (Sandbox Code Playgroud)

这种形式适用于排序和计数:

$ echo 'This test is this test.' | sed 's/\.//g;s/\(.*\)/\L\1/;s/\ /\n/g' | sort | uniq -c
      1 is
      2 test
      2 this
Run Code Online (Sandbox Code Playgroud)

改进

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
Run Code Online (Sandbox Code Playgroud)

这使用与原始命令相同类型的替换命令,只是稍作改动:

  1. s/[[:punct:]]//g 删除所有标点符号。

  2. s/.*/\L&/ 将所有大写字符转换为小写。

  3. 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/'
Run Code Online (Sandbox Code Playgroud)