如果我想删除一个字符之前的所有内容(例如“(”),我会这样做'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 次)- 直到它点亮某个目标字符并将其替换掉,或者将其替换为自身 - 就像它对一对 之间出现的任何字符所做的那样()
。