我正在尝试使用sed
在新行上获取匹配的非数字字符串
所以,如果我有字符串abc def 123 (ghi)
,我希望输出为:
(abc)
(def)
(ghi)
这就是我尝试过的:
echo "abc def 123 (ghi)" | sed -r 's/([a-z]+)/(1)n/g'
但这输出如下:
(abc)
(def)
123 ((ghi)
)
我在这里很困惑。有很多疑问:为什么2号线和3号线有领先空间?为什么使用双括号ghi
?为什么123
没有被消除?为什么,最后一行单独出现了封闭的苦咸水湖?
更新
实际上,我想从特定的域中提取URL。因此,使用评论和答案中的建议,我尝试了以下内容:
in="https://www.example.com/user1 ddsf none http://www.example.com/user2 kbu7f7yy"
echo $in | sed 's/http[s]*://www.example.com/[^ ]*/&n/g'
打印如下:
https://www.example.com/user1
ddsf none http://www.example.com/user2
kbu7f7yy
所以,我尝试了这个(如一个中所建议的(
echo $in | sed 's/.*(http[s]*://www.example.com/[^ ]*).*/1n/g'
但我最终得到了:
http://www.example.com/user2
用) (
替换行首、字母和行尾之间的任何内容,然后删除多余的括号:
sed -r 's/[^a-z]+|^|$/) (/g;s/^) | ($//g'
但我发现以下Perl解决方案更可读:
perl -lne 'print "($1)" while /([a-z]+)/g'
-n
逐行读取输入并为每行运行代码-l
从输入中删除换行符并将其添加到输出中
这可能对你有用(GNU sed(:
sed -E '/n/!s/<[[:alpha:]]+>/n(&)n/g;/^([[:alpha:]]+)/P;D' file
这会在paren中用换行符包围alpha字符串,然后只打印以打开paren、alpha字符和关闭paren开头的行。
对于url,可能是:
sed -E '/n/!s/https?S+/n&n/g;/^https?/P;D' file
使用-E
命令行选项以便使用扩展的regexps:
/n/!s/https?S+/n&n/g
如果当前行不包含任何换行符,则全局替换以http
开头的字符串,并用可选的s
替换换行符包围的同一字符串/^https?/P
如果当前图案空间的前面以带有可选s
的http
开始,则打印到并包括下一新行- 如果模式空间不为空,
D
将删除下一个新行,并重新启动sed循环(不从文件中获取下一行(
因此,将进行第一次替换,然后进行打印/删除。每次处理时,图案空间都会减少,直到它为空,然后下一行将呈现给图案空间。
sed 's/[()0-9]//g; s/[a-z]+/(&)n/g; s/ //g;'
- 删除所有括号和数字
- 环绕
(&)n
中的所有单词,其中&
是匹配单词的简写 - 删除所有空格
也可以这样做:grep -Pow '[a-z]+' | sed 's/.*/(&)/'
对于url示例,grep
比sed更容易提取单词:grep -Pow 'httpS+'
- 用于perl匹配的
-P
允许S+
表示"非空间"> -o
仅用于匹配- 用于单词匹配的
-w
(相当于bhttpS+b
(
如果出于某种原因仍要添加parens,grep -Pow 'httpS+' | sed s/.*/(&)/