使用 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
我在文件中有这段文字
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.
结果:
$ 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