PDA

View Full Version : Add a space using Sed (getting errors )


mark hunte
09-19-2004, 06:06 AM
Hi I am trying to substitute
.jpg"

to .jpg" border="2"

in a load of html files. Using

each \*.html sedx 's/\.jpg\"/\.jpg\" border\=\"2\"/g'


The each and sedx commands normally work fine but any time i want to use a
'space' between the words i get

sed: 1: "s/\.jpg\"/\.jpg\"": unterminated substitute in regular expression


Here is the sedx code if it helps

#!/bin/sh
tmp=tmp-file-for-$PPID
{ sed "$1" "$2" > $tmp \
&& mv $tmp "$2"
} || rm $tmp

And here is the each code
#!/bin/bash

if [ "$2" = "" ]; then
echo "usage: ${0##*/} filetype command-to-execcute"
exit

fi

filetype=$1
shift


for file in $filetype; do
$* "$file"
done

OSX 10.2.8

Thanks

acme.mail.order
09-19-2004, 09:06 AM
Since you say it works fine without the space, lets assume it's a shell issue. Tried a different shell?

To save you some typing in the future, you don't need to escape " and = characters, just / and '
Here, running

's/\.jpg"/\.jpg" border="2"/g'

works as you want it to.

If this is a global change, just add

img {border-width: 2px; border-color: red; border-style: solid; }

to the style sheet and you're all done!

mark hunte
09-19-2004, 03:03 PM
Thanks , I guess I was being thick and could have just used the .css file.

But I think I have been trying to figure this problem for a while and got caught up in a loop.

I Still need to sort this out though because there I times when I need to change caption text on a whole load of web pages, and this is the best/quickest way, so long as I only do single words. But I need to be able to do it with more text.


I did try your script and change the shell, but no change.
do you have a list of the ones that are installed with Osx

thanks

jbc
09-19-2004, 03:50 PM
Just a thought...have you tried escaping the space? Since the raw command works for acme, maybe your quoting is getting munged a bit being passed between variables and commands.

each \*.html sedx 's/\.jpg\"/\.jpg\"\ border\=\"2\"/g'

mark hunte
09-19-2004, 05:06 PM
Yes tried that, but no luck.

But I think your right Just a thought...have you tried escaping the space? Since the raw command works for acme, maybe your quoting is getting munged a bit being passed between variables and commands.

I just tried the sedx part on it own and it worked

sedx 's/\.jpg"/\.jpg" border="2"/g' index_4.html

so Now all I need to do is work out why the each is trashing the string?

squinty
09-20-2004, 09:27 PM
Yes tried that, but no luck.

But I think your right

I just tried the sedx part on it own and it worked

sedx 's/\.jpg"/\.jpg" border="2"/g' index_4.html

so Now all I need to do is work out why the each is trashing the string?

Bash internal commands consider the space character a line separator. It'll screw it up even if the space is escaped in a for each loop.
However, you can do something like:

newifs=$IFS;
IFS="<tab><newline>";
each \*.html sedx 's/\.jpg\"/\.jpg\" border\=\"2\"/g';
IFS=$newifs

or you could add the IFS redefinition to your 'each' code. In case you didn't guess, the variable IFS is a built-in that defines line separators for your shell.

Good luck!

PS: That "<tab><newline>" above means quote-key tab-key return-key quote-key. If you type it in literally, you'll have some really screwy line separators :).

mark hunte
09-21-2004, 02:33 PM
Squinty, you are Fantastic, that worked as I needed when put into the each
Command.
Thanks :)

I am not going to even pretend I understood why that worked.
But I did have a look in the Man Page for bash, and found

IFS The Internal Field Separator that is used for word splitting
after expansion and to split lines into words with the read
builtin command. The default value is ``<space><tab><new-
line>''.

Word Splitting
The shell scans the results of parameter expansion, command substitu-
tion, and arithmetic expansion that did not occur within double quotes
for word splitting.

The shell treats each character of IFS as a delimiter, and splits the
results of the other expansions into words on these characters. If IFS
is unset, or its value is exactly <space><tab><newline>, the default,
then any sequence of IFS characters serves to delimit words. If IFS
has a value other than the default, then sequences of the whitespace
characters space and tab are ignored at the beginning and end of the
word, as long as the whitespace character is in the value of IFS (an
IFS whitespace character). Any character in IFS that is not IFS
whitespace, along with any adjacent IFS whitespace characters, delimits
a field. A sequence of IFS whitespace characters is also treated as a
delimiter. If the value of IFS is null, no word splitting occurs.

Explicit null arguments ("" or '') are retained. Unquoted implicit
null arguments, resulting from the expansion of parameters that have no
values, are removed. If a parameter with no value is expanded within
double quotes, a null argument results and is retained.

Note that if no expansion occurs, no splitting is performed.

I think I will need to read it a couple of hundred times to understand it.
I guess what you got me to change was the defualt <space><tab><new-line> to <tab><new-line>

But I need to get a handle on the expansion stuff,
thanks again, and Boy have I got a long way to go in my learning curve.

squinty
09-21-2004, 03:59 PM
I think I will need to read it a couple of hundred times to understand it.
I guess what you got me to change was the defualt <space><tab><new-line> to <tab><new-line>

That's right. You'll find IFS is really useful if you want to have bash loop over filenames with spaces in them or anything like that.