sed usage

choppy812

New Member


Messages: 15

When I set up FreeBSD, I followed an online guide that used sed to modify a few conf files. One was like this:
# sed -i 's/datasize-cur=768M/datasize-cur=4096M/' /etc/login.conf

But now while going through a book on sed, I try this on a regular file and get an error.
$ sed -i 's/MA/Mass/' list.txt
sed: 1: "list.txt": extra characters at the end of l command


Some googling shows that some versions of sed require sed -i '' -- empty single quotes first. That does work, but if sed requires that on FreeBSD, why didn't it give me the same error when I used it on /etc/login.conf?

list.txt
Code:
John Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls PA
Eric Adams, 20 Post Road, Sudbury MA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston MA
 

olli@

Well-Known Member
Developer

Reaction score: 361
Messages: 475

When I set up FreeBSD, I followed an online guide that used sed to modify a few conf files. One was like this:
# sed -i 's/datasize-cur=768M/datasize-cur=4096M/' /etc/login.conf

But now while going through a book on sed, I try this on a regular file and get an error.
$ sed -i 's/MA/Mass/' list.txt
sed: 1: "list.txt": extra characters at the end of l command


Some googling shows that some versions of sed require sed -i '' -- empty single quotes first.
Actually, the POSIX standard does not specify the -i option at all, so different operating systems implemented it in slightly different ways. FreeBSD (and BSD in general) tries to avoid optional arguments for options (because of consistency reasons), so that's why you always have to specify one with -i.
That does work, but if sed requires that on FreeBSD, why didn't it give me the same error when I used it on /etc/login.conf?
I'm pretty sure it did. Maybe you overlooked it. Or the command was slightly different from the one you quoted above.
 

ddeimeke

New Member

Reaction score: 1
Messages: 13

But now while going through a book on sed, I try this on a regular file and get an error.
$ sed -i 's/MA/Mass/' list.txt
sed: 1: "list.txt": extra characters at the end of l command
Most probably you are running against a file with DOS line endings.

To confirm that please run the following and post the results:

$ tr -d '\r' < list.txt > newlist.txt
$ sed -i 's/MA/Mass/' newlist.txt


Cheers

Dirk
 

olli@

Well-Known Member
Developer

Reaction score: 361
Messages: 475

Most probably you are running against a file with DOS line endings.
No. Please read the error message carefully. It has nothing to do with the file; sed didn't even begin to read the file.

It is a syntax error on the command line: The -i option expects an argument, so it takes the next word ('s/MA/Mass/') as the argument for the -i option. Then it looks for the actual sed command, so it takes the next word (list.txt) as the sed command. Obviously this is not a valid sed command, and that's causing the error message.
 

ddeimeke

New Member

Reaction score: 1
Messages: 13

No. Please read the error message carefully. It has nothing to do with the file; sed didn't even begin to read the file.
Yes, sorry. I was expecting that the first example worked already.

If I read the manpage correctly you could check if capital 'i' ('I') is the parameter you need.

Cheers

Dirk
 
OP
OP
C

choppy812

New Member


Messages: 15

Ok, it must have been early, I apologize -- "sed -i " works on OpenBSD, not FreeBSD. I just tried on FreeBSD logged in as root, on login.conf.copy and got an error.
 

userxbw

Active Member

Reaction score: 14
Messages: 135

i sed in FreeBSD as such.
Code:
sed -i "" 's|someword|thisOtherWord|' file
#whereas I use to
sed -i.bak 's|word|noWord|' file
the 1st one leaves no bak file to delete. if I did just the
Code:
sed -i 's|find|replace|' file
I'd get a error as well.
Code:
[userx@FreeBSD64 ~]$ cat >> sedme
goop

[userx@FreeBSD64 ~]$ sed -i 's|goop|boop|' sedme
sed: 1: "sedme": unterminated substitute in regular expression
[userx@FreeBSD64 ~]$ sed -i ""  's|goop|boop|' sedme
[userx@FreeBSD64 ~]$ cat sedme boop
 

olli@

Well-Known Member
Developer

Reaction score: 361
Messages: 475

Not intending to insult anybody … but if people read the manual pages more carefully, threads like this one would not have to exist in the first place …
 
OP
OP
C

choppy812

New Member


Messages: 15

No offense taken. Just a simple confusion from a simple man... I'm becoming a little more competent daily. :)
 

PMc

Well-Known Member

Reaction score: 155
Messages: 471

No. Please read the error message carefully. It has nothing to do with the file; sed didn't even begin to read the file.

It is a syntax error on the command line: The -i option expects an argument, so it takes the next word ('s/MA/Mass/') as the argument for the -i option. Then it looks for the actual sed command
That doesn't make sense. According to the manpage, when there is an -i option, there is no command expected.

Code:
SYNOPSIS
     sed [-Ealnru] command [file ...]
     sed [-Ealnr] [-e command] [-f command_file] [-I extension] [-i extension]
         [file ...]
 

olli@

Well-Known Member
Developer

Reaction score: 361
Messages: 475

That doesn't make sense. According to the manpage, when there is an -i option, there is no command expected.
Code:
SYNOPSIS
     sed [-Ealnru] command [file ...]
     sed [-Ealnr] [-e command] [-f command_file] [-I extension] [-i extension]
         [file ...]
Good catch. That's a bug in the manual page. Using the -i option doesn't change the syntax of the rest of the line. In other words, the -i option should be listed with both synopsis lines.
 

PMc

Well-Known Member

Reaction score: 155
Messages: 471

Good catch. That's a bug in the manual page.
Agreed. I posted that before I got to read to Your post about "reading the manpage", so, sorry, no offense was intended.

Using the -i option doesn't change the syntax of the rest of the line. In other words, the -i option should be listed with both synopsis lines.
Check... agree, thats what the code says. So, to make this thread finally useful - can You get that into HEAD?
Also, the -l option is similar to -u option and should not be in the second line.
 

olli@

Well-Known Member
Developer

Reaction score: 361
Messages: 475

Check... agree, thats what the code says. So, to make this thread finally useful - can You get that into HEAD?
I'm afraid I'm not a committer anymore, so I have to open a bugzilla ticket like everybody else. ;)
I just did that, see PR 240556.
Also, the -l option is similar to -u option and should not be in the second line.
Apparently, when the -I, -i and -u options were added, they forgot to add them to both lines of the synopsis. For example, -u was added with this commit.

The only difference between both usages is that you have <command> as a separate argument in the first case, and -e <command> and/or -f <command> in the second case. You can't mix these two cases. But all the other options can be applied in both cases.
 

PMc

Well-Known Member

Reaction score: 155
Messages: 471

I'm afraid I'm not a committer anymore, so I have to open a bugzilla ticket like everybody else. ;)
I just did that, see PR 240556.
👍 Thank You.

Apparently, when the -I, -i and -u options were added, they forgot to add them to both lines of the synopsis. For example, -u was added with this commit.

The only difference between both usages is that you have <command> as a separate argument in the first case, and -e <command> and/or -f <command> in the second case. You can't mix these two cases. But all the other options can be applied in both cases.
Ups, it seems I made the same thinking mistake as those who did the former changes. You are right, the actual difference in the two use-cases is in the way the command code is given.

The other difference (which is kinda half-reflected in the current synopsis) is that the -u and -l options are pointless together with the -i or -I option. They are syntactically legal, but have no effect, as they work directly on the STDOUT handle, which isn't used with -i.
So, when they added the -u options, it is understandable that they didn't add it to the line where the -i option appears.
 
Top