Shell sed contortion

I'm wondering if someone can help me come up with a way of piping the output of one sed script into another...

In simple terms I have a list of items which I want to preformat and then insert them into another file at a specific location.

I could do it by creating an intermediate file, ie:

sed -f scr1 a > b
sed -f scr2 b > c

According to ChatGPT I can do something like

Insert stdin at a specific line
sed 'LINE_NUMBER r /dev/stdin' target.txt <<EOF ... EOF

but ths means nothing to me. Can anyone explain this instruction?
 
Is this not just a standard pipe:

Code:
sed  -f scr1 a | sed -f scr2  > c

Thanks for the suggestion. I'll give it a try.

I tried but can't get it to work.

I have two files. The frst one I want to reformat, and insert the result after a particular in the second file.

eg

a contains

london
new york
rome

b contains

Amsterdam
Zurich

I want to end up with

Amsterdam
London
New York
Rome
Zurich

I want to capitalise a and insert the result after line 1 of b.
 
[…] piping the output of one sed script into another... […]
The best way would be to invoke sed(1) only once, i. e. one script achieves all necessary steps. Care to show us your scripts? And sample inputs. Maybe it is not possible with sed(1), but another tool could do what you want.​
In simple terms I have a list of items which I want to preformat and then insert them into another file at a specific location.
Well, if you know the line number position ahead of time (without regex) like your reposting of some ChädGPity output suggested, it’s just a matter of recreating the file:​
Bash:
{
	head -n  50 ./contortion
	sed -f ./list_formatting_script ./list_items
	tail -n +51 ./contortion
} > ./contortion_merged
 
As the saying goes, there are many ways leading to Rome; Kai Burghardt has shown one.

Your capitalization request, as based on your example (i.e.: capitalize all words as a "preformat" action), can be done with GNU sed extensions; see 5.6 regular expression extensions - \b and 5.9.2 Upper/Lower case conversion:
Rich (BB code):
[1-0] % gsed -E 's/\b(.)/\U\1/g' a
London
New York
Rome
sed(1) does not support either \b (word designation) or \U (case converion command). If at all possible with sed(1), this would require extensive construction of sed loops and of the y command. Using awk(1) for this task for example is much more straighforward:
Rich (BB code):
[2-0] % awk '{ for ( i=1; i <= NF; i++) $i = toupper(substr($i,1,1)) substr($i,2); print }' a
London
New York
Rome

For your main OP question:
Insert stdin at a specific line
sed 'LINE_NUMBER r /dev/stdin' target.txt <<EOF ... EOF
but ths means nothing to me. Can anyone explain this instruction?
Taken literally (ad verbatim) this does not work because in this use of a heredoc the termination string must be the only contents of its last line; see 2.7.4 Here-Document. The correct way:
Rich (BB code):
$ sed '1 r /dev/stdin' b  <<EOF
> London
> New York
> Rome
> EOF
Amsterdam
London
New York
Rome
Zurich
Basically what you are asking in your OP problem was the merging of two inputs, thereby avoiding any temporary files—not something that is used often. As shown in the last example the sdtin input stream and the file b are used as inputs, both specified on the command line. Your example problem can therefore be solved without temporary files and only sed(1) and awk(1):
Rich (BB code):
[3-0] % awk '{ for ( i=1; i <= NF; i++) $i = toupper(substr($i,1,1)) substr($i,2); print }' a | sed '1 r /dev/stdin' b
Amsterdam
London
New York
Rome
Zurich
However, as mentioned in the beginning, using a base-install, the use of an awk(1) script is far more appropriate for a capitalization. Furthermore, when the line number at which the "preformat[ted]" input stream is to be inserted at a specific location becomes more complex, it would also be more practical to not use sed for that, but use another solution, for example use awk(1) there too.
 
The best way would be to invoke sed(1) only once, i. e. one script achieves all necessary steps. Care to show us your scripts?​


This is just an example.....

This is file A

Code:
# /etc/wpa_supplicant.conf written by wifimgr(8)


network={
}

This is file B

Code:
ssid="UPC240613990"
bssid=34:7a:60:d9:f8:4d
key_mgmt=WPA-PSK
proto=RSN
psk="CVRK54CV"


I want the result to look like:

Code:
# /etc/wpa_supplicant.conf written by wifimgr(8)


network={
<------>ssid="UPC240613990"
<------>bssid=34:7a:60:d9:f8:4d
<------>key_mgmt=WPA-PSK
<------>proto=RSN
<------>psk="CVRK54CV"
}

The first script is just to insert tabs which is quite straight forward but I can't work out how to insert the output into the first file at the appropriate place.
I understand that I can use something some construct like /8r + filename but this would the 8th line from stdin rather than a filename. I have no idea if that is codeable.
 
Back
Top