-2

Below is the values i have in the array

10.106.86.93,A1,3
10.106.86.93,A2,3
10.106.86.93,A2,3
10.106.86.93,A3,3
10.106.86.93,A3,3
10.106.86.93,A4,3

Need to loop through this and if the last value is equal 3 then have to merge the value of the second column

e.g.

10.106.86.93  A1,A2,A2,A3,A3,A4  3

was trying some for loop but not getting using correctly or not

while read -r line
do
    StatusValue= $line | awk -F, '{print $NF}'
    if [[${StatusValue} == "3"}]] then
       echo $line | awk -F,'{print $2}'
    fi

done <<< ${Dell_Data_Status_3}

Here i am trying to print the second value of the line when the status is 3

but not able to get the output.

error :

./SortFile.sh: line 30: syntax error near unexpected token `fi'
./SortFile.sh: line 30: `    fi'

Please let me know what is wrong here

5
  • Sorry, this is not the way StackOverflow works. Questions of the form "I want to do X, please give me tips and/or sample code" are considered off-topic. Please visit the help center and read How to Ask, and especially read Why is “Can someone help me?” not an actual question? Commented Apr 2, 2019 at 12:17
  • Sorry for that. i am trying some code and will update the question on that. Commented Apr 2, 2019 at 12:19
  • try to build on your previous question Commented Apr 2, 2019 at 12:20
  • ya but i am trying to loop through each line of the array. that i am not able to. after that from that line i can get the last element Commented Apr 2, 2019 at 12:25
  • Reading that info into a shell array and then processing it with awk is almost certainly the wrong approach to whatever it is you're trying to do. Ask a new question if you'd like help to do whatever you're trying to do the right way. Also, when asking a question related to what to do when some condition is true (e.g. last val is 3) then include cases where that condition is false in your sample input so we can better see your requirements and test a potential solution against your provided example. Commented Apr 2, 2019 at 14:52

3 Answers 3

2

Let's start with a simple bash syntax:

Below is the values i have in the array

Ok, so we have a bash array:

arr=(
10.106.86.93,A1,3
10.106.86.93,A2,3
10.106.86.93,A2,3
10.106.86.93,A3,3
10.106.86.93,A3,3
10.106.86.93,A4,3
)

Need to loop through this

Ok. First we need to output the array as newline separated list. The following will output the array:

$ printf "%s\n" "${arr[@]}"

Then we need to read the array elements and split them on the comma separator. We ise IFS variable to control on which characters bash splits elements:

printf "%s\n" "${arr[@]}" |
while IFS=, read -r ip A num; do
     : # TODO body
done

Ok. Now we can check the value of the third column and output the third if it matches 3:

printf "%s\n" "${arr[@]}" |
while IFS=, read -r ip A num; do
     if [ "$num" = 3 ]; then
          echo "$A"
     fi
done

Note that each space is important. The if [[${StatusValue} == "3"}]] then from your code is very invalid - you need a space between [[ and ${.. and a space between "3" and ]], the } is invalid. Remember, you talk to the computer using your keyboard, nothing more - each keystroke counts.

Now the hard part:

if the last value is equal 3 then have to merge the value of the second column

Well, this is simply and fastly done with awk scripting. What we need to do, is to create a map. We need to map third column value to other two columns.

But let's make a simple, stupid and very, very slow approach:

  1. Identify unique values in the third column
  2. For each unique value in the third column
    1. Get all the lines with this value as the third column
    2. Get the first column from any of the lines
    3. From the filtered lines extract second column and concatenate them
    4. Output a line

# just to have the array as a string
arrstr=$(printf "%s\n" "${arr[@]}")

# cut only the third column and get unique values
<<<"$arrstr" cut -d, -f3  | sort -u |
# for each unique third column value
while read -r num; do
    # get the columns that have that value as the third column
    filtered=$(<<<"$arrstr" awk -vIFS=, -vOFS=, '$3 = '"$num")
    # get the values of the second field only
    # substitute newline for comma
    # remove the trailing comma
    second_field_sum=$(<<<"$filtered" cut -d, -f2 | tr '\n' ',' | sed 's/,$//')
    # get the value of the first field (from the first line)
    ip=$(<<<"$filtered" head -n1 | cut -d, -f1)
    # output
    printf "%s %s %s\n" "$ip" "$second_field_sum" "$num"
done

Please check your script on shellcheck.net for errors. Most beginners error (missing quotes, typos, bad redirections, if syntax errors) are easy to fix with just listening to shellcheck messages.

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

Comments

1

Borrowing a little something from @KamilCuk, paying the debt with ++, thank you:

$ arr=(
10.106.86.93,A1,3
10.106.86.93,A2,3
10.106.86.93,A2,3
10.106.86.93,A3,3
10.106.86.93,A3,3
10.106.86.93,A4,3
)

Using awk for processing:

$ printf "%s\n" "${arr[@]}" | 
awk -F, '                          # input separator to a comma
$3==3 {                            # when the third field is 3
    f2=$2=f2 (f2==""?"":",") $2    # update the $2 to 2nd field var f2 and
    out=$0                         # ... keep printable record in out var
}
END { print out }'                 # output here

Output:

10.106.86.93 A1,A2,A2,A3,A3,A4 3

And of course that data could be in a file instead of an array.

Update as requested:

$ printf "%s\n" "${arr[@]}" | 
awk -F, -v OFS=, '                 # input and output separators to a comma
$3==3 {                            # when the third field is 3
    f2=$2=f2 (f2==""?"":",") $2    # update the $2 to 2nd field var f2 and
    out=$0                         # ... keep printable record in out var
}
END { print out }'                 # output here

10 Comments

Thanks...Worked perfectly...!!! Just One this...Need to store the output in a variable..how can i do that..??
var=$(printf ... | awk ...); echo $var
with your code, the output is coming like 10.106.86.93 A1,A2,A2,A3,A3,A4 3 as mentioned. But if i need to separate this by comma then what change needs to be done..??
Like: 10.106.86.93,A1,A2,A2,A3,A3,A4,3? You set the output field separator: awk -F, -v OFS=, ...
Sorry @james, my bad...did a silly mistake...fixed now.. thanks a ton...
|
0

You can do it in pure bash (and GNU coreutils) with this script:

#! /bin/bash
set -euo pipefail

# https://stackoverflow.com/questions/1527049
function join_by { local IFS="$1"; shift; echo "$*"; }

Dell_Data_Status_3="$(cat data)" # I made a standalone script and assume
                                 # this variable contains the raw data

# Get the list of first column elements, sorted and deduplicated
readarray -t first_col <<<"$(echo "${Dell_Data_Status_3}" | cut -d ',' -f 1 | sort -u)"

for i in "${first_col[@]}" ; do
    # get the values of the second column for every first column element
    readarray -t second_col <<<"$(echo "${Dell_Data_Status_3}" | grep "$i" | cut -d ',' -f 2)"

    # print the data. If you need another value than 3 at the end,
    # you may want to consider a loop on this value
    echo "$i $(join_by ',' "${second_col[@]}") 3"
done

Comments

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.