+#!/usr/bin/env bash
+
+read_stdin() {
+ # Desc: Consumes stdin; outputs as stdout lines
+ # Input: stdin (consumes)
+ # Output: stdout (newline delimited)
+ # Example: printf "foo\nbar\n" | read_stdin
+ # Depends: GNU bash (version 5.1.16)
+ # Version: 0.0.1
+ local input_stdin output;
+
+ # Store stdin
+ if [[ -p /dev/stdin ]]; then
+ input_stdin="$(cat -)";
+ fi;
+
+ # Store as output array elements
+ ## Read in stdin
+ if [[ -n $input_stdin ]]; then
+ while read -r line; do
+ output+=("$line");
+ done < <(printf "%s\n" "$input_stdin");
+ fi;
+
+ # Print to stdout
+ printf "%s\n" "${output[@]}";
+}; # read stdin to stdout lines
+get_median() {
+ # Desc: Gets the median from integers or floats read from stdin
+ # Input: stdin newline-delimited integers or floats
+ # Output: stdout float
+ # Depends: GNU Coreutils 8.32 (sort), bc 1.07.1
+ # Depends: BK-2020-03: read_stdin() 0.0.1,
+ # Version: 0.0.1
+
+ # Read stdin
+ list="$(read_stdin)";
+
+ # Sort list
+ list="$(printf "%s\n" "$list" | sort -n)";
+
+ # Get list length
+ list_lc="$(printf "%s\n" "$list" | wc -l)";
+
+ # Get number of lines to trim from start and end
+ if [[ $((list_lc % 2)) -eq 0 ]]; then
+ # If even
+ trim=$(( list_lc / 2 - 1 ));
+ flag_even="true";
+ else
+ # If odd
+ trim=$(( list_lc / 2 ));
+ fi;
+
+ # Trim lines
+ list="$(printf "%s\n" "$list" | tail -n+$((trim+1)) | head -n-$((trim)) )";
+
+ # Get median
+ if [[ "$flag_even" == "true" ]]; then
+ ## Average remaining two lines
+ l1="$(printf "%s\n" "$list" | head -n1)";
+ l2="$(printf "%s\n" "$list" | tail -n1)";
+ median="$( echo "( $l1 + $l2 ) / 2" | bc -l; )";
+ else
+ ## Median is simply remmaining line
+ median="$list";
+ fi;
+
+ # Output median
+ printf "%s" "$median";
+
+ # Author: Steven Baltakatei Sandoval
+ # License: GPLv3+
+}; # Returns median float from a list
+
+# Test
+shuf -i1-100 -n49 | get_median; printf "\n";
+printf "17\n5\n11.1111\n3.141592\n2\n343.4343434343434343\n" | get_median; printf "\n";