1. Overview

The sed command is a common Linux command-line text processing utility. It’s pretty convenient to process text files using this command.

However, sometimes, the text we want the sed command to process is not in a file. Instead, it can be a literal string or saved in a shell variable.

In this short tutorial, we’ll have a look at how to ask the sed command to process a literal string or shell variable.

2. Using the echo Command and Pipe

The sed command can read and process text from input files or standard input streams.

Since our text is not saved in a file, if we can somehow write the text to stdin, then sed can read it. In Linux, pipes can help us to direct stdout to stdin.

Therefore, we can first use the echo command to output the text to stdout and then pipe to the sed command. Let’s see an example:

$ echo "We love Linux." | sed 's/We/They/; s/Linux/Microsoft Windows/'
They love Microsoft Windows.

As the example above shows, echo “text” | sed solves our problem. If our text is in a shell variable, this way works as well:

$ TEXT="We love Linux"                                      
$ echo $TEXT | sed 's/We/They/; s/Linux/Microsoft Windows/'
They love Microsoft Windows

3. Using the echo Command and Process Substitution

We’ve learned to pipe the echo command’s stdout to the sed command to solve the problem. Apart from that, we can also use process substitution to solve our problem.

Process substitution can save the output of a process in a temporary file and feed the file to another process. Its template looks like this:

another_process <(process)

Back to our problem, we can output our text in a process substitution and feed it to the sed command:

$ sed 's/We/They/; s/Linux/Microsoft Windows/' <(echo "We love Linux.")
They love Microsoft Windows.

The same way works if the text is in a shell variable:

$ sed 's/We/They/; s/Linux/Microsoft Windows/' <(echo $TEXT)
They love Microsoft Windows.

4. Difference Between Pipes and Process Substitutions

So far, we’ve seen two different approaches to solve the problem: pipes and process substitution. We may want to ask, what’s the difference between pipes and process substitution? Let’s understand the difference using examples.

Pipes redirect content from stdout to stdin. However, process substitution executes a command, saves the output to a special temporary file, and then passes the filename to another command. 

The temporary file created by process substitution is actually a named pipe. Let’s verify it:

$ [[ -p <(date) ]] && echo "It is a pipe"
It is a pipe

The -p in [[…]] tests if the process substitution is a pipe.

An example may help us to understand the difference in a more straightforward way:

$ echo <(date)
/dev/fd/63

$ cat <(date)
Wed Jan  6 12:30:44 PM CET 2021

If we pass a file to the echo command, echo won’t print the file’s content. Instead, the filename will be displayed by the echo command. That’s why the first echo command in the example doesn’t show the date string.

However, if we pass a process substitution to a command accepting files, the content of the process substitution will be read. In the example above, we passed <(date) to the cat command. As we can see, the date string is printed.

Another difference between pipes and process substitutions in usage is that we cannot pipe the stdout of multiple commands using pipes. But we can do that using process substitutions.

Let’s see an example:

$ diff <(date -d 'yesterday') <(date -d 'tomorrow')
1c1
< Tue Jan  5 12:47:37 PM CET 2021
---
> Thu Jan  7 12:47:37 PM CET 2021

In the example above, we used two process substitutions to pass two different date strings as two files to the diff command to show the differences. However, we cannot achieve the same using pipes.

5. Using here-string

Another way to feed a literal text or a variable to stdin is by using here-string:

$ sed 's/We/They/; s/Linux/Microsoft Windows/' <<< "We love Linux."
They love Microsoft Windows.

$ sed 's/We/They/; s/Linux/Microsoft Windows/' <<< $TEXT
They love Microsoft Windows.

6. Conclusion

In this short article, we’ve addressed different ways to ask the sed command to work with a literal string or shell variable as input.

Moreover, we’ve understood the difference between pipes and process substitution.