如何删除一个或多个字符之前的某些字符(但不是全部)?

如何删除一个或多个字符之前的某些字符(但不是全部)?

如果我想删除一个字符之前的所有内容(例如“(”),我会这样做's/.*(//g'。现在我只想删除一个字符/某些字符之前的某些内容,在我的情况下-之前((包括空格)

我尝试了一些方法,但没有成功。一个例子是:

sed 's/ *(/(/g'

但这只删除了之前的空格,而不删除其他空格,这对我在阅读代码时有意义(它将删除空格 和 之间的所有内容(,但在此处询问之前我必须尝试一些操作),所以我尝试了这个:(这也没用)

sed 's/* (/(/g'

但这次我不明白为什么不。我认为这是因为空格是非常特殊的字符,所以我尝试用-(s/*- (/(/g's/*-* (/(/g') 代替,但它们也不起作用。

输入:

081 379 62 49 (Hems)
081-379-62-49 (Hems) 

期望的输出:

0813796249 (Hems)

答案1

您想删除之前的所有空格和破折号(吗?然后您需要使用字符类或“括号表达式”,包括空格和破折号:[- ]

sed -e 's/[- ]*(/(/g'

查看man 7 regex并搜索bracket expression更多详细信息。

使用您提到的输入(081 379 62 49 (Hems)081-379-62-49 (Hems)),您可以使用以下命令来完成awk

awk -F'(' 'BEGIN {OFS=" ("} ; {gsub(/[- ]/,"",$1) ; print}'

这告诉 awk 用作(字段分隔符,然后使用该gsub()函数从第一个字段(电话号码)中删除空格和破折号。输出字段分隔符 (OFS) 设置为((空格和()以产生正确的输出。

例如

echo -e "081 379 62 49 (Hems)\n081-379-62-49 (Hems)" | 
    awk -F'(' 'BEGIN {OFS=" ("} ; {gsub(/[- ]/,"",$1) ; print}'
0813796249 (Hems)
0813796249 (Hems)

顺便说一句,如果电话号码后面没有空格或破折号(例如在 内(...)),您也可以使用 sed 执行此操作:

echo -e "081 379 62 49 (Hems)\n081-379-62-49 (Hems)" | 
    sed -e 's/[ -]//g ; s/(/ (/'

这会从输入行中删除所有空格和破折号,然后在 . 之前放回一个空格(。如果括号内有多个单词(注释/名称字段?),输出将会变得非常丑陋。

在 sed 中可能有一些极其复杂的方法可以正确完成此操作,方法是复制电话号码以保留空间并在那里修改它,然后将其重新插入到输出行中,但使用 awk 更容易做到这一点。

答案2

这适用于sed

printf %s\\n '081 379 62 49 (Hems)' \
             '081-379-62-49 (Hems)' |
sed 's/\( ([^)]*)\)\{0,1\}[ -]\{0,1\}/\1/g'

0813796249 (Hems)
0813796249 (Hems)

技巧是sed当它没有删除您想要删除的字符串之一时,让其删除一个空字符串。通过这种方式,g局部替换可以跨越整个模式空间,消除一堆空东西 -( \{0,1\}- 出现 0 或 1 次)- 直到它点亮某个目标字符并将其替换掉,或者将其替换为自身 - 就像它对一对 之间出现的任何字符所做的那样()

相关内容