使用 sed 在文本文件中查找匹配项和创建新行时出错

Error finding matches and creating new lines in a text file using sed

我在文件中有这段文字

random text 1.- random text 2. random text 3.- random 22 text 4. random text

我想在每个数字后跟一个点之前创建一个新行。这是我的代码:

for number in {1..4}
do
var=$(sed -n "s/.*\([^0-9]$number\.[^0-9]\).*//p" file)
echo $var
sed -i "s/$var/\n$var/g" file 
done

这是我得到的结果:

random text
 1.- random text
 2. random text
 3.- random
 2. text
 4. random text

我不明白为什么如果没有点,它会在数字 22 之前创建一个新行。预期结果是这样的:

random text
1.- random text
2. random text
3.- random 22 text
4. random text

谁能帮我解释一下我的错误在哪里?非常感谢

number=2 你得到 var=' 2.'

这被送入最后一个 sed 命令作为 / 2./\n 2./g 其中第一个 2. 表示将文字 2 与任何其他单个字符匹配(.) 这就是它最终匹配 22 的原因。然后让你更困惑一点,\n 2. 说要插入文字 2. 因此 22 被替换为 2.

考虑:

$ echo '22' | sed 's/2./2./'
2.

当前代码的一个快速修复是使用 parameter substitution 添加反斜杠以转义 $var 中的 .:

for number in {1..4}
do
    var=$(sed -n "s/.*\([^0-9]$number\.[^0-9]\).*//p" file)
    var="${var/./\.}"      # replace "." with "\."
    echo $var
    sed -i "s/$var/\n$var/g" file
done

$ cat file
random text
 1.- random text
 2. random text
 3.- random 22 text
 4. random text

前导 space 是第一个 sed 命令中第一个 [^0-9] 的匹配项,因为它在括号内,所以它被认为是捕获组的一部分,因此包含在</code> 参考。尝试将左括号向右移动一个字符,例如:</p> <pre><code>for number in {1..4} do # replace this: #var=$(sed -n "s/.*\([^0-9]$number\.[^0-9]\).*//p" file) # with this: var=$(sed -n "s/.*[^0-9]\($number\.[^0-9]\).*//p" file) var="${var/./\.}" echo $var sed -i "s/[[:space:]]*$var/\n$var/g" file done

注意: 我在 $var 之前添加了 [[:space:]]* 以匹配任何白色 space;替换 (\n$var) 将有效地从现在的 line-before $var.

的末尾删除所说的白色 space

结果:

$ cat file
random text
1.- random text
2. random text
3.- random 22 text
4. random text

我会使用一个 sed 命令来编写它:

sed 's/ \([0-9][0-9]*\.\)/\
/g' file

单次使用sed

$ sed -i.bak 's/[0-9]*\.[^0-9]*/\n&/g' file
random text
1.- random text
2. random text
3.- random 22 text
4. random text