这可能是一个非常基本的问题,但我无法为此制作衬垫。
考虑这一行
foo@some_text/48183 bar@another-test/22787 xyz@some_another_text/2291
我想将所有内容从“@”替换为以逗号分隔的空格。 所以我的预期输出应该是
foo,bar,xyz
我正在尝试sed -e 's/@.*[^ ]/,/g'
替换直到空间,但是它正在替换整行(在编写常规exp时不太好)。
任何帮助将不胜感激。
答案 0 :(得分:3)
您可以在@
字符之前找到并捕获除@
之外的任何1个字符,然后匹配@
以及除空格之外的任何0 +字符,后跟0 +空白字符,并将占位符替换为组1和逗号。然后,您将不得不删除尾随的逗号。
查看sed demo:
s='foo@some_text/48183 bar@another-test/22787 xyz@some_another_text/2291'
echo "$s" | sed -E 's/([^@]+)@[^[:space:]]*[[:space:]]*/\1,/g' | sed 's/,$//'
请注意,您也可以使用POSIX ERE版本的sed 's/\([^@][^@]*\)@[^[:space:]]*[[:space:]]*/\1,/g'
内容。在BRE POSIX中,您应该转义(
和)
以形成捕获组,+
量词应该被转义,或者用aa*
构造替换。
<强>详情
([^@]+)
- 捕获第1组:除@
以外的其他字符@
- @
字符[^[:space:]]*
- 除了空格之外的0个字符[[:space:]]*
- 0+空白字符 \1
是使用捕获组#1捕获的文本的占位符。
第二个sed 's/,$//'
用于删除字符串末尾的尾随,
。
答案 1 :(得分:2)
关注awk
可能会对您有所帮助。
awk 'BEGIN{OFS=","}{for(i=1;i<=NF;i++){sub(/@.*/,"",$i)}} 1' Input_file
解决方案第二: 从Wiktor Stribizew的帖子中获取代码并进行一些修改,现在将其转换为单个sed
。
sed -E 's/([^@]+)@[^[:space:]]*[[:space:]]*/\1,/g;s/,$//' Input_file
答案 2 :(得分:2)
正则表达式(@.*[^ ]
)的匹配部分的基本问题是.*
在第一个@
之后几乎匹配源字符串的整个休息
(一个非常常见的错误)和[^ ]
匹配最后一个非空格字符。
如果您使用@\S+\s*
作为匹配部分,则\S+
匹配&#34;非空格&#34;部分
(例如some_text/48183
)和\s*
此后匹配可选空格。
此替换提供foo,bar,xyz,
,因此您应该以某种方式删除最后一个逗号。
答案 3 :(得分:2)
即使可能更多pipy
,你也可以反过来做。
$ echo "foo@some_text/48183 bar@another-test/22787 xyz@some_another_text/2291" | (tr ' ' ',' | grep -oP '(?=,|^)[^@]+' | tr -d '\n'; echo "")
foo,bar,xyz
您可以直接提取相关部分,而不是替换部分字符串。
<强>说明:强>
tr ' ' ','
以逗号替换所有空格。 grep -oP '(?=,|^)[^@]+'
获取@
之前的所有内容。它使用带有环视的perl正则表达式(强制约束前面的字符是逗号或字符串的开头,并接受除@
之外的所有字符。tr -d '\n'
用于删除grep
echo ""
,则可以省略\n
。然后,您可以在tr ' ' ',' | grep -oP '(?=,|^)[^@]+' | tr -d '\n'