Udit Gupta
Udit Gupta

Reputation: 3272

passing variables from one side of linux pipe to other

I would like to print everything in a file beyond line which contain word stats -

Now what i am trying to do is -

$a=sed -n '/Stats/=' file.txt | sed -n '$a,$p' file.txt

Of course it doesn't work the above suggested way but what else should I do ?

Ex- suppose the word is a line no. 40 then i want to print everything from line 41 to end.

Please tell me how to pass variables form one side of pipe to other ? Also If anyone could some other way to do it, it would be if great help.

Thanks

Upvotes: 0

Views: 1602

Answers (3)

Digital Trauma
Digital Trauma

Reputation: 15996

Directly passing variables from one side of Linux pipe to other is not possible because the commands on either side of the pipe are executed in a fork()ed subshell. That means that these commands are executed in their own copy (one per side of the pipe) of the parent shell process. Thus they will receive copies of the variables in the parent process, but won't be able to directly modify the original variables in the parent. It follows that the copies of the variables in subshells for either side of the pipe will be completely independent of each other, other than the fact that they should inherit the same initial values from the parent.

To illustrate this we can run the following commands:

a=100
(echo "LHS pre: $a" 1>&2; ((a++)); echo "LHS post: $a" 1>&2) | ( echo "RHS pre: $a" 1>&2 ; ((a+=10)); echo "RHS post: $a" 1>&2 )
echo "Parent final: $a" 1>&2

The output is:

RHS pre: 100
RHS post: 110
LHS pre: 100
LHS post: 101
Parent final: 100

Here we set the variable a to 100 in the parent shell process. The LHS and RHS (left-hand side and right-hand side) of the pipe on the second command both receive copies of this variable. The LHS prints the copy variable, increments it by 1, then prints again. The RHS prints the copy variable, increments it by 10, then prints again. Then the parent shell prints its original version of the variable. We can see that the LHS and RHS subshells are incrementing their copies of the variable completely independently. And then we also see the original in the parent is completely unaffected by the modifications from the LHS and RHS subshells.


Now I'm done with theory. Here are some solutions for the problem you are actually running into. Perhaps not so elegant, but for those of us that do everything we can to avoid reading the and manpages, here's a couple of alternatives:

  1. with "simple" tools - head, tail, grep and cut
  2. with pure

.

ubuntu@ubuntu:~$ cat stats.txt 
The first line
The 2nd line
the line with stats in it
another line
another line with stats
another line
the last line
ubuntu@ubuntu:~$ tail -n-$(($(grep -n stats stats.txt | head -n1 | cut -d: -f1)+1)) stats.txt 
another line
another line with stats
another line
the last line
ubuntu@ubuntu:~$ fl=""; while read -r line; do [ "$fl" ] && echo -e $line; [[ $line =~ stats ]] && fl=1; done < stats.txt
another line
another line with stats
another line
the last line

Upvotes: 1

Jotne
Jotne

Reputation: 41454

Another awk solution

awk '/Stats/ {f=1} f' file

When word Stats is found, set flag f to true.
If f is true, do default action, print the line, same as {print $0}

Upvotes: 1

MattSizzle
MattSizzle

Reputation: 3175

Sorry it is going to be super quick, have to get back to work. You want AWK for this one.

awk '/Stats/,0' FILE

Output:

Stats
s
dfsdfsd


sdfsdfsdfsd

File:

lwjeawfasdfas
sdafdsfasdfasdf

asdfasdfasdfsadf


asdfas
1122


Stats
s
dfsdfsd


sdfsdfsdfsd

It matches all the lines starting with a line that matches "pattern1" and continuing until a line matches "pattern2" (inclusive). In this one-liner "pattern1" is a regular expression "/Stats/" and "pattern2" is just 0 (false). So this one-liner prints all lines starting from a line that matches "/Stats/" continuing to end-of-file (because 0 is always false, and "pattern2" never matches).

Have fun...

Upvotes: 2

Related Questions