我正在使用 sed 来查找和替换模式。
我的模式是“-”
我有以下数据
>1-2-3-4-5 29238232382083e-9
>1-2-3-4-5 29238232382083e-9
>1-2-3-4-5 29238232382083e-9
>1-2-3-4-5 29238232382083e-9
我想用“*”替换 1-2-3-4-5 中的“-”,这样我就可以得到 1*2*3*4*5
但是,当我用sed -i -e '/-/*/g 进行替换时
所有“-”都会受到影响,甚至是 29238232382083e*9 的 29238232382083e-9。
我可以做什么来替换所有“-”,除了位于“e”之后的“-”,如本例中的 29238232382083e-9 ?
答案1
sed 's/\([^e]\)-/\1*/g' /path/to/input
详细说明该sed
声明:
\([^e]\)-
在这里,我们使用分组来查找除e
后跟连字符之外的任何字符\1*
- 在这里,我们用该分组中的任何内容替换找到的内容(例如连字符之前的非 e),后跟替换该连字符的星号。
请注意,这不适用于作为一行第一个字符的连字符;为此,我们必须添加一个特殊情况:
sed 's/\([^e]\)-/\1*/g;s/^-/*/' /path/to/input
这很相似,但用星号替换了该行第一个字符的连字符。由于它是第一个字符,因此前面不能有e
。
答案2
选一个:
awk方法:
awk '{ gsub("-","*",$1) }1' OFS='\t' file
gsub("-","*",$1)
- 将所有-
内容替换*
为第一个字段内的内容
珀尔方法:
perl -lae '$,="\t"; $F[0] =~ y/-/*/; print @F' file
-a
- 自动分割$_
到数组中@F
$,="\t"
\t
- 使用(选项卡)连接字段$F[0] =~ y/-/*/
- 将所有内容翻译-
到*
第一个字段内$F[0]
输出(对于两者awk和珀尔方法):
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
sed方法:
sed 'h; s/ .*$//; y/-/*/;G; s/\n[^[:space:]]*//' file
输出(对于sed方法):
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
>1*2*3*4*5 29238232382083e-9
答案3
虽然可以使用 POSIX sed 完成,但由于表达式简单,这里使用 GNU sed 显示:
sed -e '
s/\S\s/&\n/;:a
s/-\(.*\)/*\1/;ta
s/\n//
' yourfile
结果
>1*2*3*4*5 29238232382083e*9
>1*2*3*4*5 29238232382083e*9
>1*2*3*4*5 29238232382083e*9
>1*2*3*4*5 29238232382083e*9
解释
- 标记我们希望发生更改的边界。
- 然后我们设置一个循环并逐步执行其中的更改。