What is the purpose of the "-" in sh script line: ext="$(echo $ext | sed 's/\./\\./' -)"

StackOverflow https://stackoverflow.com/questions/14781654

  •  07-03-2022
  •  | 
  •  

Question

I am porting a sh script that was apparently written using GNU implementation of sed to BSD implementation of sed. The exact line in the script with the original comment are:

# escape dot in file extension to grep it
ext="$(echo $ext | sed 's/\./\\./' -)"

I am able to reproduce a results with the following (obviously I am not exhausting all possibilities values for ext) :

ext=.h; ext="$(echo $ext | sed 's/\./\\./' -)"; echo [$ext]

Using GNU's implementation of sed the following is returned:

[\.h]

Using BSD's implementation of sed the following is returned:

sed: -: No such file or directory
[]

Executing ext=.h; ext="$(echo $ext | sed 's/\./\\./')"; echo [$ext] returns [\.h] for both implementation of sed.

I have looked at both GNU and BSD's sed's man page have not found anything about the trailing "-". Googling for sed with a "-" is not very fruitful either.

Is the "-" a typo? Is the "-" needed for some an unexpected value of $ext? Is the issue not with sed, but rather with sh?

Can someone direct me to what I should be looking at, or even better, explain what the purpose of the "-" is?

Was it helpful?

Solution

On my system, that syntax isn't documented in the man page, but it is in the 'info' page:

sed OPTIONS... [SCRIPT] [INPUTFILE...]

If you do not specify INPUTFILE, or if INPUTFILE is -',sed' filters the contents of the standard input.

Given that particular usage, I think you could leave off the '-' and it should still work.

OTHER TIPS

You got your specific question answered BUT your script is all wrong. Take a look at this:

# escape dot in file extension to grep it
ext="$(echo $ext | sed 's/\./\\./')"

The main problems with that are:

  1. You're not quoting your variable ($ext) so it will go through file name expansion plus if it contains spaces will be passed to echo as multiple arguments instead of 1. Do this instead:

    ext="$(echo "$ext" | sed 's/\./\\./')"
    
  2. You're using an external command (sed) and a pipe to do something the shell can do trivially itself. Do this instead:

    ext="${ext/./\.}"
    
  3. Worst of all: You're escaping the RE meta-character (.) in your variable so you can pass it to grep to do an RE search on it as if it were a string - that doesn't make any sense and becomes intractable in the general case where your variable could contain any combination of RE metacharacters. Just do a string search instead of an RE search and you don't need to escape anything. Don't do either of the above substitution commands and then do either of these instead of grep "$ext" file:

    grep -F "$ext" file
    fgrep "$ext" file
    awk -v ext="$ext" 'index($0,ext)' file
    
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top