2

for example, if I want to write a script that get strings as arguments, and I want to insert them to array array_of_args and then I want to sort this array and to make sorting array.

How can I do it?

I thought to sort the array (and print it to stdout) in the next way:

array_of_args=("$@")
# sort_array=()
# i=0
    for string in "${array_of_args[@]}"; do
        echo "${string}"
    done | sort

But I don't know how to insert the sorting values to array ( to sort_array)..

1 Answers1

1

You can use following script to sort input argument that may contain whitespace, newlines, glob characters or any other special characters:

#!/usr/bin/env bash

local args=("$@") # create an array of arguments
local sarr=()     # initialise an array for sorted arguments

# use printf '%s\0' "${args[@]}" | sort -z to print each argument delimited
# by NUL character and sort it

# iterate through sorted arguments and add it in sorted array
if (( $# )); then
   while IFS= read -rd '' el; do
      sarr+=("$el")
   done < <(printf '%s\0' "${args[@]}" | sort -z)
fi

# examine sorted array
declare -p sarr
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Thanks, yes adding `-r` twice was a typo – anubhava Mar 06 '18 at 21:42
  • 1
    Hmm. Offhand, I don't see an answer this good on the longstanding duplicate -- there's at least one that gets close as an aside/afterthought, but nowhere it appears to be the primary recommendation. Might copy this there? – Charles Duffy Mar 06 '18 at 21:44
  • @anubhava Can I print any element from array with `\n` by single line-code? –  Mar 06 '18 at 21:49
  • @CharlesDuffy: [This answer](https://stackoverflow.com/a/27083506/548225) comes very close – anubhava Mar 06 '18 at 21:54
  • @Jor.Mal: Can you clarify your question a bit more on what you want to do? – anubhava Mar 06 '18 at 21:55
  • @anubhava Yes. given array `arr` can I print each element from `arr` in another line (something like that: `${arr[0]}\n${arr[1]}\n...`) by a single line of code? –  Mar 06 '18 at 21:57
  • 2
    @Jor.Mal, `(( ${#arr[@]} )) && { printf '%s\n' "${arr[@]}" | sort; }` is your one line of code. – Charles Duffy Mar 06 '18 at 22:00
  • You can use `printf '%s\n' "${sarr[@]}"` provided array elements don't have `\n` in it. – anubhava Mar 06 '18 at 22:01
  • 1
    @anubhava, ...one caveat there is that it'll print a single newline if the array is empty, hence the `(( ${#arr[@]} ))` check to suppress output in the empty case. S'ppose that's actually a problem with the original/primary code in the answer too (changing `args=( )` to `sarr=( '' )`). – Charles Duffy Mar 06 '18 at 22:02
  • @anubhava More a little question, if I want to do a `for` loop about all the elements of `arr` apart of the first element how can I do it? I tried to do something like that: `for element in "${arr[@:1]}"; do ...` , but it's not working –  Mar 06 '18 at 22:33
  • 1
    Use: `for element in "${arr[@]:1}"; do ...done` – anubhava Mar 06 '18 at 22:37