2 # Copyright (C) 2014 Ian Kelling
3 # This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
6 local help="Usage: appendu [OPTION]... FILE [LINE_SET]...
10 A LINE_SET is one or more lines. Append LINE_SET to FILE if it does not exist in
11 FILE. If no LINE_SET argument is given, read lines from stdin, and treat each
12 as a single LINE_SET. Appended text is output to the terminal.
14 -s don't try to use sudo when it would help us read or write the file
15 -- stop processing arguments
16 --help display this message"
18 local readsudo writesudo x
strings string content
22 if [[ $1 == --help ]]; then
25 elif [[ $1 == -s ]]; then
28 elif [[ $1 == -- ]]; then
36 if [[ ${#@} == 0 ]]; then
37 echo "error: need 1 or more arguments"
45 local file_exists
=false
46 if [[ -e $file ]]; then
48 [[ -r $file ]] || readsudo
=sudo
49 [[ -w $file ]] || writesudo
=sudo
51 local dir
="$(dirname "$file")"
52 if [[ -d $dir ]]; then
53 [[ ! -w $dir ]] && writesudo
=sudo
55 echo "appendu error: $dir does not exist"
64 if (( $# == 0 )); then
74 # fix files with no newline at the end.
75 # the following command won't work right on them.
76 # e = run script, $a\ means append following text, but there is none,
77 # so sed only does what it always does when it was supposed to modify a file,
78 # which is append a newline if there was none.
80 # command substitution removes any trailing newlines, so we have to add
81 # a non-newline ending, we randomly chose "b", then remove it.
82 content=$($readsudo cat "$file"; echo b) content=${content%b}
84 # we aren't using regex because we want to match
strings,
85 # but we also want our match to start at the beginning of a line,
86 # or the beginning of the file, and to end at a line ending.
87 # So we do some slick bash to match this.
92 for string
in "${strings[@]}"; do
93 [[ $content != $start"$string"$end ]] && $writesudo tee -a "$file"<<<"$string"
96 for string
in "${strings[@]}"; do
97 $writesudo tee -a "$file"<<<"${strings[@]}"