Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing from string to array not working as expected in Bash

Tags:

bash

I want to put the result of the sort method into an array where each cell contains a word. I tried this code but only part of the $file is printed and its not sorted:

#!/bin/bash
for file in `ls ${1}` ; do
    if [[ ! ($file = *.user) ]] ; then
        continue
    fi

    arr=(`sort -nrk4 $file`)
    echo ${arr[*]}

done

Why isnt this working? How can I do this?

Data file:

name1 01/01/1994 a 0
name2 01/01/1994 b 5
name3 01/01/1994 c 2

If I run the sort line only (sort -nrk4 $file), this is whats printed:

name2 01/01/1994 b 5
name3 01/01/1994 c 2
name1 01/01/1994 a 0

When I run the 2 lines above, this is what its printed:

 name1 01/01/1994 a 0
like image 631
Omar Avatar asked Dec 11 '25 02:12

Omar


1 Answers

In order for each line of the sort output to be put into its own array element, IFS needs to be set to a newline. To output the array, you need to iterate over it.

#!/bin/bash
for file in $1; do
    if [[ ! $file = *.user ]]; then
        continue
    fi

    saveIFS=$IFS
    IFS=$'\n'
    arr=($(sort -nrk4 "$file"))
    IFS=$saveIFS
    for i in "${arr[@]}"
    do
        echo "$i"
    done

done

Alternatively, don't reset IFS, don't use a loop for output and the following command will output the elements separated by newlines since the first character of IFS is used for the output separator when * is used for the subscript in a quoted context:

echo "${arr[*]}"

Remember, quoting fixes everything.

Don't use ls in a for loop. If $1 may contain globbing, then it should be left unquoted. It not, then it should be quoted in case the directory or filename may contain whitespace characters. Ideally, the contents of $1 should be validated before they're used here.

The comparison operators have higher precedence than the negation operator so the parentheses are unnecessary.

For command substitution, $() is preferred over backticks. They're more readable and easier to use nested.

And finally, when variables are expanded, the should be quoted. Also, @ should almost always be used to subscript arrays.

like image 50
Dennis Williamson Avatar answered Dec 12 '25 18:12

Dennis Williamson