0

I have a text file with the following details.

#test.txt

team_id   team_level  team_state
23            2         
21            4
45            5

I have an array in my code teamsstatearr=(12 34 45 ...) and I want to be able add the value in the array to the third column. The array could have many elements and the test.txt file is just a small portion that I have shown below.

Details of the file contents:

The text file has only three headers. The headers are separated by tab. The number of rows in the file are equivalent to the number of items in the array as well.

Thus my test.txt would look like the following.

team_id   team_level  team_state
23            2         12
21            4         34
45            5         45

(many more rows are present)

What I have done as of now: I don't see the file have the update in the third column with the values.

# Write the issue ids to file
for item in "${teamstatearr[@]}"
do
  printf '%s\n' "item id in loop: ${item}"
  awk -F, '{$2=($item)}1' OFS='\t',  test.txt
done

I would appreciate if anyone could help me find the most easiest and efficient way to do it.

0

1 Answer 1

1

If you don't mind a slightly different table layout, you could do:

teamsstatearr=(12 34 45)
{
  # print header
  head -n1 test.txt

  # combine the remaining lines of test.txt and the array values
  paste <(tail -n+2 test.txt) <(printf '%s\n' "${teamsstatearr[@]}")

  # use `column -t` to format the output as table
} | column -t

Output:

team_id  team_level  team_state
23       2           12
21       4           34
45       5           45

To write the output to the same file, you can redirect the output to a new file and overwrite the original file with mv:

teamsstatearr=(12 34 45)
{
  head -n1 test.txt
  paste <(tail -n+2 test.txt) <(printf '%s\n' "${teamsstatearr[@]}")
} | column -t > temp && mv temp test.txt

If you have sponge from the moreutils package installed, you could to this without a temporary file:

teamsstatearr=(12 34 45)
{
  head -n1 test.txt
  paste <(tail -n+2 test.txt) <(printf '%s\n' "${teamsstatearr[@]}")
} | column -t | sponge test.txt

Or using awk and column (with the same output):

teamsstatearr=(12 34 45)
awk -v str="${teamsstatearr[*]}" '
  BEGIN{split(str, a)}  # split `str` into array `a`
  NR==1{print; next}    # print header 
  {print $0, a[++cnt]}  # print current line and next array element
' test.txt | column -t
Sign up to request clarification or add additional context in comments.

8 Comments

Does this code write the contents back to the test.txt file? Can you confirm that with me
I dont understand the purpose of this line NR==1{print; next} # print header and where did you get the cnt from. I dont see it initialized anywhere earlier. I am new to bash scripting so excuse me if I ask stupid questions.
You code just print but I asked to be able to write the update column back to the test.txt file. Please update the code
Updated the answer. The cnt variable doesn't need to be initialized in awk. The default value is 0 if you use the variable the first time, so a[++cnt] gets the value from a[1] on the first call.
Use the same method as in the bash example. Redirect the output to a temporary file and overwrite the original file afterwards: awk ... test.txt | column -t > temp && mv temp test.txt
|

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.