+++ /dev/null
-#!/bin/bash
-# Copyright (C) 2014 Ian Kelling
-# This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
-
-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 "$@"
+++ /dev/null
-#!/bin/bash
-# Copyright (C) 2014 Ian Kelling
-# This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
-
-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
-}
--- /dev/null
+#!/bin/bash
+# Copyright (C) 2014 Ian Kelling
+# This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
+
+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 "$@"
--- /dev/null
+#!/bin/bash
+# Copyright (C) 2014 Ian Kelling
+# This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
+
+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
+}
+++ /dev/null
-#!/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"; }
-
-