0

I'm stuck on a bash problem. The script should read each line in data.txt and assign it to an array before checking if each array value is empty. If the array value is empty, the text "unknown" should replace the empty value. Line 2 would otherwise have the text $Author.

data.txt

07/22/2022, 00:00:00

NASA Reveals Webb Telescope's first images of unseen universe
"We are elated to celebrate this extraordinary day with the world," said Greg Robinson, Webb program director at NASA Headquarters.
webb, telescopes, images, reveals, galaxies, star, unseen, nasa, universe, nebula, webbs, gas, view, space

bashscript.sh

# assign each line in data.txt to array
readarray data < data.txt

# for each value in array
for i in "${data[@]}"; do

    # check if value is null
    if [ -z "$data[i]" ]; then

        # if value is null, assign text "unknown" to value
        data[i]="unknown"

    fi

done


Author=${data[1]}

echo "author: $Author"

ouput:

author:

expected output:

author: unknown

Thanks for reading/helping....

3
  • "${!data[@]}" to get indexes instead of values. Commented Jul 14, 2022 at 17:19
  • @Shawn Thanks. However I'm not sure how to apply that knowledge to the code above Commented Jul 14, 2022 at 17:31
  • That would give you values of i that can be used as array indexes Commented Jul 14, 2022 at 17:52

2 Answers 2

2

The main problem with your script is that a string consisting of a new-line character isn't considered a null string. The check for the empty line should have been if [ "${data[i]}" = $'\n' ]. Also you should have used a C-style for loop. Below is a corrected version of your script:

#!/bin/bash

readarray data < data.txt

# for each value in array
for ((i = 0; i < ${#data[@]}; ++i)); do
    # check if value is null
    if [  "${data[i]}" = $'\n' ]; then

        # if value is null, assign text "unknown" to value
        data[i]="unknown"

    fi

done

Author=${data[1]}

echo "author: $Author"

Or, as suggested by glenn jackman, use the readarry with the -t flag and check for the empty string as [ -z "${data[i]}" ]

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

1 Comment

Or, use readarray -t ... that strips off the trailing newline.
2

In bash, try to avoid explicit iteration over the data. Such an approach is not only slow, but also prone to errors, especially for beginners. Instead, use tools designed for the job, which will do the looping for you.

sed 's/^$/unknown/' puts the string unknown into all empty lines.

To retrieve a single line, you can use head | tail or sed again.

Your entire script can be boiled down to

sed -n '2{s/^$/unknown/;s/^/author: /;p;q;}' data.txt

1 Comment

Thank you. I have restructured my code to utilise your method. However, I have not changed the accepted answer as it is more relevant to the question.

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.