Home > Enterprise >  Generic "append to file if not exists" function in Bash
Generic "append to file if not exists" function in Bash

Time:02-01

I am trying to write a util function in a bash script that can take a multi-line string and append it to the supplied file if it does not already exist.

This works fine using grep if the pattern does not contain \n.

if grep -qF "$1" $2
then
    return 1
else
    echo "$1" >> $2
fi

Example usage

append 'sometext\nthat spans\n\tmutliple lines' ~/textfile.txt

I am on MacOS btw which has presented some problems with some of the solutions I've seen posted elsewhere being very linux specific. I'd also like to avoid installing any other tools to achieve this if possible.

Many thanks

CodePudding user response:

If the files are small enough to slurp into a Bash variable (you should be OK up to a megabyte or so on a modern system), and don't contain NUL (ASCII 0) characters, then this should work:

IFS= read -r -d '' contents <"$2"

if [[ "$contents" == *"$1"* ]]; then
    return 1
else
    printf '%s\n' "$1" >>"$2"
fi
  • In practice, the speed of Bash's built-in pattern matching might be more of a limitation than ability to slurp the file contents.
  • See the accepted, and excellent, answer to Why is printf better than echo? for an explanation of why I replaced echo with printf.

CodePudding user response:

Using awk:

awk '
BEGIN {
  n = 0 # length of pattern in lines
  m = 0 # number of matching lines
}
NR == FNR {
  pat[n  ] = $0
  next
}
{
  if ($0 == pat[m])
    m  
  else if (m > 0 && $0 == pat[0])
    m = 1
  else
    m = 0
}
m == n {
  exit
}
END {
  if (m < n) {
    for (i = 0; i < n; i  )
      print pat[i] >>FILENAME
  }
}
' - "$2" <<EOF
$1
EOF
  • Related