Reputation: 5404
Say, for example, I have the following array:
files=( "foo" "bar" "baz fizzle" )
I want to pipe the contents of this array through a command, say sort
, as though each element where a line in a file. Sure, I could write the array to a temporary file, then use the temporary file as input to sort
, but I'd like to avoid using a temporary file if possible.
If "bar fizzle"
didn't have that space character, I could do something like this:
echo ${files[@]} | tr ' ' '\012' | sort
Any ideas? Thanks!
Upvotes: 9
Views: 8399
Reputation: 74949
I like to wrap common items like this into function to make it easier to understand what's going on:
pipeArray() {
for ITEM in $@; do
echo "$ITEM"
done
}
DATA=('a' 'c' 'b')
pipeArray ${DATA[@]} | sort
Upvotes: 1
Reputation: 21
For sorting files I would recommend sorting in zero-terminated mode (to avoid errors in case of embedded newlines in file names or paths):
files=(
$'fileNameWithEmbeddedNewline\n.txt'
$'saneFileName.txt'
)
echo ${#files[@]}
sort <(for f in "${files[@]}" ; do printf '%s\n' "$((i+=1)): $f" ; done)
sort -z <(for f in "${files[@]}" ; do printf '%s\000' "$((i+=1)): $f" ; done) | tr '\0' '\n'
printf "%s\000" "${files[@]}" | sort -z | tr '\0' '\n'
find . -type f -print0 | sort -z | tr '\0' '\n'
sort -z
reads & writes zero-terminated lines!
Upvotes: 2
Reputation: 126088
Yet another solution:
printf "%s\n" "${files[@]}" | sort
Upvotes: 7
Reputation: 1485
SAVE_IFS=$IFS
IFS=$'\n'
echo "${files[*]}" | sort
IFS=$SAVE_IFS
Of course it won't work properly if there are any newlines in array values.
Upvotes: 3
Reputation: 799510
sort <(for f in "${files[@]}" ; do echo "$f" ; done)
Upvotes: 11