如果行尚未出现在文件中,如何将包含$符号的文字行添加到文件中?

时间:2018-11-28 22:33:36

标签: bash

给出以下文字行(即$'s不是 引入变量):

if $var-with-dollar-and-space == 'local2' and $msg contains 'Disp' then /path/to/file

我必须检查该行是否出现在文件中(完全按原样),如果没有,则将其添加到文件中。
我尝试了多种转义字符的方法-但是无法正确处理。
以下是尝试MCVE的尝试(不起作用):

#!/bin/bash -xv

LINE_TO_ADD_IF_ABSENT="if \$var-with-dollar-and-space == 'local2' and \$msg contains 'Disp' then /path/to/file"
ESCAPED_LINE='if $var-with-dollar-and-space == \'local2\' and $msg contains \'Disp\' then /path/to/file'

LOG_FILE='/tmp/mcve.log'

if [[ ! -e $LOG_FILE ]]; then
  touch $LOG_FILE
fi

if [[ -w $LOG_FILE ]]; then
  $( fgrep -q "$ESCAPED_LINE" ${LOG_FILE} )
  ret=$?
  if [[ $ret != 0 ]]; then
    echo $ESCAPED_LINE >> $LOG_FILE
  fi
fi

您是否可以提出一项修正案(或其他方法),使我能够创建一个bach脚本,如果该行不包括在内,则该行将在文件的顶部添加该行该文件?

编辑:

为响应@Charles和@David的评论,以下是经过修改的MCVE及其运行结果:

$ cat /tmp/mcve.sh
#!/bin/bash -xv

line_to_add_if_absent='if $var-with-dollar-and-space == \'local2\' and $msg contains \'Disp\' then /path/to/file'
escaped_line='if $var-with-dollar-and-space == \'local2\' and $msg contains \'Disp\' then /path/to/file'

log_file="/tmp/mcve.log"

if [[ ! -e $log_file ]]; then
  touch $log_file
fi

if [[ -w $log_file ]]; then
  fgrep -q ${line_to_add_if_absent} ${log_file}
  ret=$?
  if [[ $ret != 0 ]]; then
    echo $escaped_line >> $log_file
  fi
fi

$ /tmp/mcve.sh
#!/bin/bash -xv

line_to_add_if_absent='if $var-with-dollar-and-space == \'local2\' and $msg contains \'Disp\' then /path/to/file'
escaped_line='if $var-with-dollar-and-space == \'local2\' and $msg contains \'Disp\' then /path/to/file'

log_file="/tmp/mcve.log"

if [[ ! -e $log_file ]]; then
  touch $log_file
fi

if [[ -w $log_file ]]; then
  fgrep -q ${line_to_add_if_absent} ${log_file}
  ret=$?
  if [[ $ret != 0 ]]; then
    echo $escaped_line >> $log_file
  fi
fi

/tmp/mcve.sh: line 4: unexpected EOF while looking for matching `''
/tmp/mcve.sh: line 20: syntax error: unexpected end of file
$ 

1 个答案:

答案 0 :(得分:3)

以下在实践中效果很好:

#!/bin/bash -xv

line_to_add_if_absent="if \$var-with-dollar-and-space == 'local2' and \$msg contains 'Disp' then /path/to/file"
log_file='/tmp/mcve.log'

[[ -e $log_file ]] || touch -- "$log_file"

if [[ -w $log_file ]]; then
  if fgrep -q -e "$line_to_add_if_absent" "$log_file"; then
    : "do nothing here; line is already present"
  else
    printf '%s\n' "$line_to_add_if_absent" >>"$log_file"
  fi
fi

我唯一要做的更改是删除不必要/无用的ESCAPED_LINE,并使用带文字内容的变量。 (报价也已修复; echo $ESCAPED_LINE不可靠,并且echoprintf替换,因为echo语句中的反斜杠具有未定义的行为;另请参阅应用程序用法和RATIONALE the POSIX specification for echo