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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With