From: Ian Kelling Date: Fri, 1 Aug 2014 15:06:32 +0000 (-0700) Subject: simplify and rename to teeu X-Git-Url: https://iankelling.org/git/?a=commitdiff_plain;h=9742f5f097a6d818d44562e3bc46fb2893f013ce;p=tee-unique simplify and rename to teeu --- diff --git a/appendu b/appendu deleted file mode 100755 index 460e363..0000000 --- a/appendu +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash -# Copyright (C) 2014 Ian Kelling -# This program is under GPL v. 3 or later, see - -appendu() { - local help="Usage: appendu [OPTION]... FILE [LINE_SET]... - -Append unique. - -A LINE_SET is one or more lines. Append LINE_SET to FILE if it does not exist in -FILE. If no LINE_SET argument is given, read lines from stdin, and treat each -as a single LINE_SET. Appended text is output to the terminal. Duplicate -LINE_SETs are treated the same. - - -- stop processing arguments - [-h|--help] display this message" - - - while true; do - if [[ $1 == --help || $1 == -h ]]; then - echo "$help" - return - elif [[ $1 == -- ]]; then - shift - break - else - break - fi - done - - if [[ ${#@} == 0 ]]; then - echo "error: need 1 or more arguments" - echo "$help" - return 1 - fi - - local file="$1" - shift - - local new_file=true - if [[ -e $file ]]; then - new_file=false - else - local dir="$(dirname "$file")" - if [[ ! -d $dir ]]; then - echo "appendu error: $dir does not exist" - return 1 - fi - fi - - local strings line - if (( $# == 0 )); then - unset IFS - while read -r line; do - strings+=( "$line" ) - done - else - strings=( "$@" ) - fi - - if ! $new_file; then - if [[ ! -r $file ]]; then - echo "appendu error: cannot read or write $file" - return 1 - fi - if [[ ! -w $file ]]; then - echo "appendu error: cannot read or write $file" - return 1 - fi - # fix files with no newline at the end. - # the following command won't work right on them otherwise. - # e = run script, $a\ means append following text, but there is none, - # so sed only does what it always does when it was supposed to modify a file, - # which is append a newline if there was none. - sed -i '$a\' "$file" - # command substitution removes any trailing newlines, so we have to add - # a non-newline ending, we randomly chose "b", then remove it. - local content=$(cat "$file"; echo b) - content=${content%b} - fi - - local reset_extglob=false - ! shopt extglob >/dev/null && reset_extglob=true - shopt -s extglob - # we aren't using regex because we want to match strings, - # but we also want our match to start at the beginning of a line, - # or the beginning of the file, and to end at a line ending. - # So we do some slick bash to match this. - local start="?(* -)" - local end=" -*" - local return_code string return_code - for string in "${strings[@]}"; do - if $new_file || [[ $content != $start"$string"$end ]]; then - if ! tee -a "$file"<<<"$string"; then - return_code=$? - echo "appendu error: error writing to $file" - return $return_code - fi - fi - done - $reset_extglob && shopt -u extglob - return 0 -} -appendu "$@" diff --git a/appendu-function b/appendu-function deleted file mode 100644 index 35f16eb..0000000 --- a/appendu-function +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -# Copyright (C) 2014 Ian Kelling -# This program is under GPL v. 3 or later, see - -appendu() { - local help="Usage: appendu [OPTION]... FILE [LINE_SET]... - -Append unique. - -A LINE_SET is one or more lines. Append LINE_SET to FILE if it does not exist in -FILE. If no LINE_SET argument is given, read lines from stdin, and treat each -as a single LINE_SET. Appended text is output to the terminal. Duplicate -LINE_SETs are treated the same. - - -- stop processing arguments - [-h|--help] display this message" - - - while true; do - if [[ $1 == --help || $1 == -h ]]; then - echo "$help" - return - elif [[ $1 == -- ]]; then - shift - break - else - break - fi - done - - if [[ ${#@} == 0 ]]; then - echo "error: need 1 or more arguments" - echo "$help" - return 1 - fi - - local file="$1" - shift - - local new_file=true - if [[ -e $file ]]; then - new_file=false - else - local dir="$(dirname "$file")" - if [[ ! -d $dir ]]; then - echo "appendu error: $dir does not exist" - return 1 - fi - fi - - local strings line - if (( $# == 0 )); then - unset IFS - while read -r line; do - strings+=( "$line" ) - done - else - strings=( "$@" ) - fi - - if ! $new_file; then - if [[ ! -r $file ]]; then - echo "appendu error: cannot read or write $file" - return 1 - fi - if [[ ! -w $file ]]; then - echo "appendu error: cannot read or write $file" - return 1 - fi - # fix files with no newline at the end. - # the following command won't work right on them otherwise. - # e = run script, $a\ means append following text, but there is none, - # so sed only does what it always does when it was supposed to modify a file, - # which is append a newline if there was none. - sed -i '$a\' "$file" - # command substitution removes any trailing newlines, so we have to add - # a non-newline ending, we randomly chose "b", then remove it. - local content=$(cat "$file"; echo b) - content=${content%b} - fi - - local reset_extglob=false - ! shopt extglob >/dev/null && reset_extglob=true - shopt -s extglob - # we aren't using regex because we want to match strings, - # but we also want our match to start at the beginning of a line, - # or the beginning of the file, and to end at a line ending. - # So we do some slick bash to match this. - local start="?(* -)" - local end=" -*" - local return_code string return_code - for string in "${strings[@]}"; do - if $new_file || [[ $content != $start"$string"$end ]]; then - if ! tee -a "$file"<<<"$string"; then - return_code=$? - echo "appendu error: error writing to $file" - return $return_code - fi - fi - done - $reset_extglob && shopt -u extglob - return 0 -} diff --git a/teeu b/teeu new file mode 100755 index 0000000..87ba60b --- /dev/null +++ b/teeu @@ -0,0 +1,31 @@ +#!/bin/bash +# Copyright (C) 2014 Ian Kelling +# This program is under GPL v. 3 or later, see + +appendu() { + local help="Usage: appendu [-h|--help] FILE + +Tee unique. Append each stdin line if it does not exist in the file + + [-h|--help] display this message" + + + if [[ $1 == --help || $1 == -h ]]; then + echo "$help" + return + fi + + if [[ ${#@} == 0 ]]; then + echo "error: need 1 or more arguments" + echo "$help" + return 1 + fi + + local MAPFILE + mapfile -t + for line in "${MAPFILE[@]}"; do + grep -xFq "$line" "$1" &>/dev/null || tee -a "$1" <<<"$line" + done + return 0 +} +teeu "$@" diff --git a/teeu-function b/teeu-function new file mode 100644 index 0000000..33347f7 --- /dev/null +++ b/teeu-function @@ -0,0 +1,30 @@ +#!/bin/bash +# Copyright (C) 2014 Ian Kelling +# This program is under GPL v. 3 or later, see + +appendu() { + local help="Usage: appendu [-h|--help] FILE + +Tee unique. Append each stdin line if it does not exist in the file + + [-h|--help] display this message" + + + if [[ $1 == --help || $1 == -h ]]; then + echo "$help" + return + fi + + if [[ ${#@} == 0 ]]; then + echo "error: need 1 or more arguments" + echo "$help" + return 1 + fi + + local MAPFILE + mapfile -t + for line in "${MAPFILE[@]}"; do + grep -xFq "$line" "$1" &>/dev/null || tee -a "$1" <<<"$line" + done + return 0 +} diff --git a/test/test b/test/test deleted file mode 100755 index ce169c4..0000000 --- a/test/test +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -l -x=$(mktemp) -appendu $x<<'EOF' -aa -bb -EOF - -y=$(mktemp) -tee -a $y<<'EOF' -aa -bb -EOF - - -output="$( -appendu $x<<'EOF' -cc -aa -caa -bb - -dd -EOF -)" - -good_output='cc -caa - -dd' - -[[ $output == "$good_output" ]] || { echo check1 failed; echo "$output != $good_output"; } - -echo "$good_output" >> $y - - -diff $x $y || echo check2 failed diffing $x and $y - -output=$(appendu $x "aa -ee" "bb") - -good_output="aa -ee" - -[[ $output == $good_output ]] || { echo check3 failed; echo "$output != $good_output"; } - -