0

Can anyone explain why the following doesn't work please?

list

the letter is d
the number is 4
the number is 2
the letter is g

script.sh

#!/bin/bash

cat "$1" | grep letter | array=($(awk '{print $4}'))

for i in "${array[@]}"
do
  :
  echo $i
done

If I run this bash script.sh list I expect the array to print d and g, but it doesn't. I think its because of how I am trying to set the array.

2 Answers 2

3

I think its because of how I am trying to set the array.

Each command in a pipeline | is run in a subshell - as a separate process. The parent process does not "see" variable changes from a child process.

Just:

array=($(grep letter "$1" | awk '{print $4}'))

or

array=($(awk '/letter/{print $4}' "$1"))

Run variable assignment in the parent shell.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah ok thanks. I used the top one but you missed a ")". Works great.
1

You should assign the complete row of piped commands to a variable.

array=($(cat "$1" | grep letter | awk '{print $4}'))

The cat and grep command can be combined with awk, but why do you want an array?
I think you want the process each element in one loop, so first remove the double quotes:

for i in ${array[@]}
do
  :
  echo $i
done

Next, try to do this without an array

while read -r i; do
  :
  echo $i
done < <(awk '/letter/ {print $4}' "$1")

1 Comment

You are so right. I wanted to do so, but I started with copying the question. Corrected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.