views:

158

answers:

2

Is there any way to fit in 1 line using the pipes the following:

output of

sha1sum $(xpi) | grep -Eow '^[^ ]+'

goes instead of 456

sed 's/@version@/456/' input.txt > output.txt
+1  A: 

This is not possible using pipes. Command nesting works though:

sed 's/@version@/'$(sha1sum $(xpi) | grep -Eow '^[^ ]+')'/' input.txt > output.txt

Also note that if the results of the nested command contain the / character you will need to use a different character as delimiter (#, |, $, and _ are popular ones) or somehow escape the forward slashes in your string. This StackOverflow question also has a solution to the escaping problem. The problem can be solved by piping the command to sed and replacing all forward slashes (for escape characters) and backslashes (to avoid conflicts with using / as the outer sed delimiter).

The following regular expression will escape all \ characters and all / characters in the command:

sha1sum $(xpi) | grep -Eow '^[^ ]+' | sed -e 's/\(\/\|\\\|&\)/\\&/g'

Nesting this as we did above we get this solution which should properly escape slashes where needed:

sed 's/@version@/'$(sha1sum $(xpi) | grep -Eow '^[^ ]+'  | sed -e 's/\(\/\|\\\|&\)/\\&/g')'/' input.txt > output.txt

Personally I think that looks like a mess as one line, but it works.

Trey
@Trey: yea I know about that one, so there is no way to do it in `one line`, using pipes perhaps ?
Michael
@Michael: sorry I misread your question. I just modified it to work in one line. I do not believe it would be possible with pipes as you would need to spawn off a subcommand, not redirect output directly to the input of another command (which is what pipes are for)
Trey
@Trey: thanks for the update, but semicolon scenario doesn't work either...
Michael
@Michael: My first solution does not use semicolons. It uses command nesting which is the closest you'll get to "piping" in this case.
Trey
@Trey: yea, this one works like a charm. Is there any way to escape `/` somehow? because there could be some other command instead of sha1sum, where I don't really know the output?
Michael
@Michael: I just modified the question and added a solution that should escape the `/` and `\` characters in the command output of the nested command.
Trey
+2  A: 

Um, I think you can nest $(command arg arg) occurances, so if you really need just one line, try

 sed "s/@version@/$(sha1sum $(xpi) | grep -Eow '^[^ ]+')/" input.txt \
     > output.txt

But I like Trey's solution putting it one two lines; it's less confusing.

Jonathan
@Trey: sed won't see the $; the shell will have executed `sha1sum $(xpi) | grep ...` before it attempts to run sed with the output from `sha1sum | grep` embedded in the command line.
Jonathan Leffler