Reputation: 8765
I need to replace several URLs in a text file with some content dependent on the URL itself. Let's say for simplicity it's the first line of the document at the URL.
What I'm trying is this:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \1 | head -n 1)/" file.txt
This doesn't work, since \1
is not set. However, the shell is getting called. Can I somehow push the sed
match variables to that subprocess?
Upvotes: 1
Views: 2777
Reputation: 1825
Late reply, but making sure people don't get thrown off by the answers here -- this can be done in gnu sed using the e
command. The following, for example, decrements a number at the beginning of a line:
echo "444 foo" | sed "s/\([0-9]*\)\(.*\)/expr \1 - 1 | tr -d '\n'; echo \"\2\";/e"
will produce:
443 foo
Upvotes: 0
Reputation: 404
The accept answer is just plain wrong. Proof:
Make an executable script foo.sh
:
#! /bin/bash
echo $* 1>&2
Now run it:
$ echo foo | sed -e "s/\\(foo\\)/$(./foo.sh \\1)/"
\1
$
The $(...)
is expanded before sed is run.
Upvotes: 4
Reputation: 360315
Try this:
sed "s/^URL=\(.*\)/\1/" file.txt | while read url; do sed "s@URL=\($url\)@TITLE=$(curl -s $url | head -n 1)@" file.txt; done
If there are duplicate URLs in the original file, then there will be n^2 of them in the output. The @ as a delimiter depends on the URLs not including that character.
Upvotes: 1
Reputation: 75976
So you are trying to call an external command from inside the replacement pattern of a sed substitution. I dont' think it can be done, the $... inside a pattern just allows you to use an already existent (constant) shell variable.
I'd go with Perl, see the /e option in the search-replace operator (s/.../.../e).
UPDATE: I was wrong, sed plays nicely with the shell, and it allows you do to that. But, then, the backlash in \1
should be escaped. Try instead:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \\1 | head -n 1)/" file.txt
Upvotes: 3