Two curious questions

Hi,

I have been thinking about a few things that I have no idea of how to do with a scripting language (awk/sed I know to make proper use of just these 2).

  1. Is there a way to have persistent variables? Say a variable that will be held in memory, and which can be accessed by subsequent scripts, without having to write it to a file and re use it later.

  2. Is there a way to retrieve results of a command before a pipe, say for example

cat filex | awk '{print $2}' | awk '{sum+=$1}END{print sum}'

is there a way that I can get to see the $2 values without writing to a file?

Probably both of these questions can be answered by using different scripts that do more than one function, I just wanted to know if there is a in-built/ default way of doing this.

I don't know what you are trying to do exactly, but I think this is what you want.

  1. use export to make variables public:
var=test
export var
  1. The only way I know is to store it in a variable:
cat filex | var=$(awk '{print $2}') ; echo $var | awk '{sum+=$1}END{print sum}'

Hi,

Thanks for the response, I am not doing anything specifically, I was just curious.

I have used export before...y didnt I think of that! Thanks.

If you want to "see" the intermediate results on your screen, put a | tee /dev/tty | into your pipe.

2 Likes

No, there's not a "global" kind of variable. Child processes inherit exported variables from their parents, but it goes no further than that. This is why we have things like /etc/profile.

a) There is a limit to how much stuff you can cram in a single shell variable. On some systems, this can be as small as a screenful or so, so don't go overboard.

b) If you're doing awk | awk | sed | cut | kitchen | sink, you probably could have done that all in one awk and saved yourself a lot of bother and CPU time. You don't need to use awk twice here:

awk '{ sum += $2 } END { print sum }' inputfile

c) That's also a useless use of cat, since awk does not need cat's help to read a file. You can use it as shown above, listing the filename on the end.

To answer question 2, there's actually a few ways to set more than one variable at once. read is a particularly flexible way of doing so. It helps if you know how many are coming, though, or can convince certain ones to come first. Everything you didn't list will get crammed into the last variable you list.

read SUM NUMBERS <<EOF
`awk '{ sum += $2; A[++L]=$0 } END { print sum ; for(N=1; N<=L; N++) print A[N]}' inputfile`
EOF

I saved all the numbers in the awk array A so I could print them later. This lets me print the sum first, and then the rest, letting me pick the sum out from the front with read.

You could also do

set -- `awk '{ sum += $2; A[++L]=$0 } END { print sum ; for(N=1; N<=L; N++) print A[N]}' inputfile`

SUM=$1
shift
REST="$*"
1 Like

Thanks Corona688 and RudiC....really appreciate it. :slight_smile:

You know what though? On second look, I can't think of any point saving those numbers when you already have them in a file. It's just as easy to use them right from the file, and you'll have no worries about running out of space in your variable.

while read A NUM G
do
       echo "NUM is $NUM"
done < inputfile

The A is so NUM reads the second column, and the G catches all the columns that come after it (if any) so they don't also get dumped in NUM.

1 Like