我需要在文本文件中替换多个URL,其中一些内容取决于URL本身。让我们说简单一点,它就是URL上文档的第一行。
我正在尝试的是:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \1 | head -n 1)/" file.txt
这不起作用,因为未设置\1
。但是,shell被调用了。我可以以某种方式将sed
匹配变量推送到该子流程吗?
答案 0 :(得分:4)
接受答案是完全错误的。证明:
制作可执行文字foo.sh
:
#! /bin/bash
echo $* 1>&2
现在运行它:
$ echo foo | sed -e "s/\\(foo\\)/$(./foo.sh \\1)/"
\1
$
在运行 sed 之前,$(...)
已展开。
答案 1 :(得分:3)
所以你试图从sed替换的替换模式中调用外部命令。我不认为它可以完成,模式中的$ ...只允许你使用已经存在的(常量)shell变量。
我选择Perl,请参阅search-replace运算符中的/ e选项(s /.../.../)。
UPDATE :我错了,sed很好地使用了shell,它可以让你做到这一点。但是,\1
中的反弹应该被转义。请尝试改为:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \\1 | head -n 1)/" file.txt
答案 2 :(得分:1)
试试这个:
sed "s/^URL=\(.*\)/\1/" file.txt | while read url; do sed "s@URL=\($url\)@TITLE=$(curl -s $url | head -n 1)@" file.txt; done
如果原始文件中存在重复的URL,则输出中将有n ^ 2个URL。 @作为分隔符取决于不包括该字符的URL。
答案 3 :(得分:0)
迟到的回复,但确保人们不会被这里的答案所抛弃 - 这个可以使用{{1>在 gnu sed 中完成命令。例如,以下代码在行的开头递减一个数字:
e
将产生:
echo "444 foo" | sed "s/\([0-9]*\)\(.*\)/expr \1 - 1 | tr -d '\n'; echo \"\2\";/e"