lhunath/scripts

trim function fails with glob characters and it collapses all lines into a single line

Closed this issue · 1 comments

Since trim uses the $(cat) expansion, it will expand glob characters if set +f is enabled. The issue is fixed with, either turning it off with set -f, or use the trim2 function.

Also, all the lines are collapsed into a single line. I do not think (guess?) this is desired, so, I changed this behavior also in the trim2 function.

#!/bin/bash

#  ______________________________________________________________________
# |__ Trim ______________________________________________________________|
#
#       trim lines ...
#
# Trim the whitespace off of the beginning and end of the given lines.
# Each argument is considdered one line; is treated and printed out.
#
# When no arguments are given, lines will be read from standard input.
#
trim() {

    # Initialize the vars.
    local lines
    local line
    local oIFS

    # Get the lines.
    lines=( "$@" )
    if (( ! ${#lines[@]} )); then
        oIFS=$IFS; IFS=$'\n'
        lines=( $(cat) )
        IFS=$oIFS
    fi

    # Trim the lines
    for line in "${lines[@]}"; do
        line=${line##*([[:space:]])}; line=${line%%*([[:space:]])}
        printf "%s" "$line"
    done
} # _____________________________________________________________________

trim2() {

    # Initialize the vars.
    local lines
    local line
    local IFS
    local separator
    local trailingNewline=true

    # Get the lines.
    lines=( "$@" )
    if (( ! ${#lines[@]} )); then
      while read -r line; do lines+=("$line"); done

      [[ $line ]] && {
        lines+=("$line")
        trailingNewline=
      }
    fi

    # Trim the lines
    for line in "${lines[@]}"; do
        line=${line##*([[:space:]])}; line=${line%%*([[:space:]])}
        printf '%s%s' "$separator" "$line"
        separator=$'\n'
    done

    [[ $trailingNewline ]] && printf '\n'
} # _____________________________________________________________________




tempdir=$(mktemp -d)
trap 'rm -rf "$tempdir"' EXIT
cd "$tempdir" || exit 1

touch {a..c}

printf %s\\n '-- trim --'
trim  <<< $'1\n*' | sed -n l
printf \\n

printf %s\\n '-- trim2 --'
trim2 <<< $'1\n*' | sed -n l
printf \\n

printf %s\\n '-- trim --'
printf 'a\nb' | trim  | od -t x1 -An -v
printf \\n

printf %s\\n '-- trim2 --'
printf 'a\nb' | trim2 | od -t x1 -An -v
printf \\n

printf %s\\n '-- trim --'
printf 'a\nb\n' | trim  | od -t x1 -An -v
printf \\n

printf %s\\n '-- trim2 --'
printf 'a\nb\n' | trim2 | od -t x1 -An -v
printf \\n

And the output:

dualbus@debian:~$ bash trim 
-- trim --
1abc$

-- trim2 --
1$
*$

-- trim --
 61 62

-- trim2 --
 61 0a 62

-- trim --
 61 62

-- trim2 --
 61 0a 62 0a

dualbus@debian:~$ 

I've just rewritten it with sed instead. Probably faster, too.

2befd20