Skip to content

Instantly share code, notes, and snippets.

@sehrgut
Last active March 20, 2019 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sehrgut/3e27ad1297f1b7238fdc to your computer and use it in GitHub Desktop.
Save sehrgut/3e27ad1297f1b7238fdc to your computer and use it in GitHub Desktop.
like xargs for stdin
#!/bin/bash
# todo: keep or discard record separator
# todo: record sep within line?
# todo: line delim param
# todo: print0
# todo: verbose mode showing objects being passed and util being invoked, etc.
VERSTRING='xsplit/v0.2'
RECORD_MODE_NULL=0
RECORD_MODE_LINE=1
RECORD_MODE_RE=2
RECORD_MODE_COUNT=3
COUNT=0
REGEX=''
DELIM=''
RECORD_MODE=$RECORD_MODE_LINE
function print-usage() {
cat <<EOF
Usage: xsplit [-0|-R regex|-n number] [utility [argument ...]]
xsplit finds objects on stdin, piping them individually to <utility>
-0: expect a null record separator between objects, instead of newline
-R|--regex [regex]: treat lines matching <regex> as record separators
-n|--count|--number [number]: Set the maximum number of lines taken from
standard input for each invocation of utility
-V|--version: print version information
EOF
}
while [ -n "$1" ]; do
case "$1" in
-0)
RECORD_MODE=$RECORD_MODE_NULL
;;
--print0) #not implemented
;;
-n|--number|--count)
COUNT="$2"
RECORD_MODE=$RECORD_MODE_COUNT
shift
;;
-R|--regex)
REGEX="$2"
RECORD_MODE=$RECORD_MODE_RE
shift
;;
-h|-u|--help|--usage)
print-usage
true
exit
;;
-V|--version)
echo "$VERSTRING"
exit 0
;;
*)
break
;;
esac
shift
done
# set default chunk delimiter
if [[ -z "$DELIM" ]]; then
case "$RECORD_MODE" in
$RECORD_MODE_NULL)
DELIM=$'\0'
;;
$RECORD_MODE_LINE|$RECORD_MODE_RE|$RECORD_MODE_COUNT)
DELIM=$'\n'
;;
esac
fi
# set default utility
if [[ -z "$1" ]]; then
set -- cat
fi
BUF=''
N=0
while read -r -d"$DELIM" line; do
case "$RECORD_MODE" in
$RECORD_MODE_COUNT)
((N++))
BUF+="$line""$DELIM"
if [[ $N -eq $COUNT ]]; then
echo -n "$BUF" | "$@"
BUF=""
N=0
fi
;;
$RECORD_MODE_RE)
BUF+="$line""$DELIM"
if [[ $line =~ $REGEX ]]; then
echo -n "$BUF" | "$@"
BUF=""
fi
;;
$RECORD_MODE_LINE|$RECORD_MODE_NULL)
#todo: handle \0 out, maybe with --print0
printf "%s%c" "$line" "$DELIM" | "$@"
;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment