I want to write a short deployment script which enters the contents of javascript-files into the single html file. These js files are currently declared as:

  <script src="js/jquery-1.8.2.js"></script>
  <script src="js/jquery.rotate-2.2.js"></script>
  <script src="js/underscore.js"></script>
  <script src="js/backbone.js"></script>
  <script src="js/backbone.dualstorage.js"></script>
  <script src="js/favourites.js"></script>
  <script src="js/menuItem.js"></script>
  <script src="js/companies.js"></script>
  <script src="js/lectures.js"></script>
  <script src="js/banquette.js"></script>
  <script src="js/menu.js"></script>

I got the fallowing sed script which almost does what I want:

sed -r -e '/<script src="(.*)">/r \1' -e '/<script src="(.*)">/d' index.html

The result of running this sed command with the above input is empty string. I'm uncertine what part of \1 is failing. Is it because references don't work outside of s commands?


sed -r -e 's/<script src="(.*)">/\1/'

Results in:

And so on ...

So obviously the regexp matches the right thing.

Is there any way to debug what \1 holds in the first command to perhaps see if the path is incorrect?


It doesn't work that way. As you say, back references don't work outside of s commands.

You could do it with awk or perl with:

perl -pe 's{<script src="(.*?)">}{
  local$/;open F,"<$1";"<script>".<F>}ge'
  • Great thanks! Though why did you put the ? after .* – Rovanion Nov 24 '12 at 17:15
  • 1
    In <script src="foo"></script><a href="...">, .* would match foo></script><a href="..., while .*? (non-greedy version) only matches foo. – Stéphane Chazelas Nov 24 '12 at 17:23
  • I've never encountered non-greedy .* before since sed doesn't support it. Is there documentation for when non-greedy .* stops? – Rovanion Nov 24 '12 at 17:28
  • 1
    See perldoc perlre. It matches as little as possible. I was introduced by perl but is now found in many other regex syntaxes in other languages. – Stéphane Chazelas Nov 24 '12 at 17:33

GNU sed's e command could be a solution:

sed '
/<script src="/ {
  s/.*<script src="\([^"]\+\)">.*/cat \1/
' index.html

e will execute the content of pattern space as the command if without an argument, so rewrite the matched line as a shell command like cat js/foobar.js would do the trick. The output of the command replaces the pattern space.

Your Answer

