Asked  7 Months ago    Answers:  5   Viewed   119 times

I'm trying to use

sed -i -e "s/.*seb.*/    "$ftp_login_template"/" $ftp_dir

however I get this error:

sed: -e expression #1, char 34: unknown option to `s'

I don't understand why since this works perfectly:

sed -i -e "s/.*wbspassword.*/    "wbspassword": "$password",/" $user_conf

Any ideas as to what I'm doing wrong?

Could this be the problem? ftp_login_template=${user}:${password}:24:86::/var/lib/clit.${user}/downloads:/bin/false"

 Answers

10

The problem is with slashes: your variable contains them and the final command will be something like sed "s/string/path/to/something/g", containing way too many slashes.

Since sed can take any char as delimiter (without having to declare the new delimiter), you can try using another one that doesn't appear in your replacement string:

replacement="/my/path"
sed --expression "s@pattern@$replacement@"

Note that this is not bullet proof: if the replacement string later contains @ it will break for the same reason, and any backslash sequences like 1 will still be interpreted according to sed rules. Using | as a delimiter is also a nice option as it is similar in readability to /.

Tuesday, June 1, 2021
 
RahulG
answered 7 Months ago
14

OS X sed handles the -i argument differently to the Linux version.

You can generate a command that might "work" for both by adding -e in this way:

#      vv
sed -i -e 's|(.*).o:|$(OBJ_DIR)/1.o $(OBJ_DIR)/1.d $(TEST_OBJ_DIR)/1_utest.o:|' $@

OS X sed -i interprets the next thing after the -i as a file extension for a backup copy of the in-place edit. (The Linux version only does this if there is no space between the -i and the extension.) Obviously a side affect of using this is that you will get a backup file with -e as an extension, which you may not want. Please refer to other answers to this question for more details, and cleaner approaches that can be used instead.

The behaviour you see is because OS X sed consumes the s||| as the extension (!) then interprets the next argument as a command - in this case it begins with t, which sed recognizes as a branch-to-label command expecting the target label as an argument - hence the error you see.

If you create a file test you can reproduce the error:

$ sed -i 's|x|y|' test
sed: 1: "test": undefined label 'est'
Thursday, June 3, 2021
 
e_i_pi
answered 7 Months ago
89

The quotes and double quotes are causing problems. You are using them in view of the slashes in the string. In sed you can use another delimiter, such as a #.

sed -e 's#socketPath:https://localhost:9091#socketPath:/socket#g' 
$WEB_CONF
Friday, July 23, 2021
 
Keat
answered 5 Months ago
60

(Compiling an answer from comments, the know-how is by melpomene and AlexP.)

What is that '' after sed -i?

-i means in-place, that is, edit in the file directly.
-i '' means edit in place a file whose name is the empty string.
Since there probably is no file whose name is the empty string, sed complains that it cannot read it.

Note 1 platform dependency:
The syntax of -i is one difference between GNU sed and sed from mac os.

Note 2 "usual" order of arguments:
The -e switch to indicate the sed code allows having it in between file names.
This is a trap (in which I for example got caught embarassingly), by making you trip over your expectations of what you find where in an sed command line.
It allows
sed -i filename -e "expression" AnotherFileName
which is an unintentionally camouflaged version of
sed -i'NoExtensionGiven' "expression" filename AnotherFileName.

Wednesday, July 28, 2021
 
Troncoso
answered 5 Months ago
81

One of the values contains a slash. You need to escape it, or use a different delimiter.

Additionally, you are needlessly stringing together multiple invocations where a single one would do. The cat is also useless.

sed -e "s@PORT2@${PORT}@ig" 
    -e 's/IP2/IPADDRESS/ig'  
    -e 's/USER2/USER/ig' 
    -e 's/PASS2/PASSWORD/ig'  /crawler/bc_daemon.php > bc_daemon.php

Unfortunately, not all sed dialects are compatible. If yours doesn't like multiple -e options, try a single string of newline-separated sed commands. I'm providing the second script in this syntax as an example.

sed "s!GITHUB!${REPO}!ig
    s!COINNAME!${NAME}!ig"  /crawler/bc_layout.php > bc_layout.php

If your values could contain @ or ! as well, you will need to pick a different delimiter. Any nonalphanumeric ASCII character will do, but backslash and quotes are obviously problematic.

Saturday, July 31, 2021
 
John Oleynik
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share