【问题标题】:Bash script: Using variables in executing sed in Freebsd which expects \ afters aBash 脚本:在 Freebsd 中执行 sed 时使用变量,它期望 \ afters a
【发布时间】:2018-01-30 15:42:01
【问题描述】:

我正在尝试在 Freebsd 的 sed 命令中使用变量。 Freebsd 中的 sed 在 a 之后需要 \。基本上,如果文件中的特定行与模式匹配,我想附加一行。我正在使用 sed 的附加功能。

#!/usr/bin/bash

SYSLOG_SERVER="192.168.1.36"
SYSLOG_PORT="514"
syslog_conf_file="/etc/syslog.conf"
send_logs() {
    logs=(messages auth.log )
    send_logs[0]=`awk '(index($2, "messages") != 0) {print $1}' $syslog_conf_file`
    send_logs[1]=`awk '(index($2, "auth.log") != 0) {print $1}' $syslog_conf_file`
    for (( i = 0 ; i < ${#send_logs[@]} ; i++ ))
    do
        if [ ! -z "${send_logs[$i]}" ]; then
            send_logs[i]=${send_logs[i]}" \t"@$SYSLOG_SERVER:$SYSLOG_PORT
            sed  "/${logs[$i]}$/a\
            ${send_logs[$i]} \
            " $syslog_conf_file
        fi
    done
}

我正面临这个错误。变量打印正确,但我运行脚本的方式是错误的。我该如何解决这个问题?

root@Great# bash temp.sh
send_logs *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err \t@192.168.1.36:514
logs messages
sed: 1: "/messages$/a            ...": command a expects \ followed by text
send_logs auth.info;authpriv.info \t@192.168.1.36:514
logs auth.log
sed: 1: "/auth.log$/a            ...": command a expects \ followed by text

sed 的预期输入示例:

root@Great# sed   '/messages$/a\                                      
 *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err @192.168.1.36:514 \
' /etc/syslog.conf  

预期输出:

*.err;kern.warning;auth.notice;mail.crit        /dev/console
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err   /var/log/messages
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err @192.168.1.36:514 
security.*                  /var/log/security
auth.info;authpriv.info             /var/log/auth.log

【问题讨论】:

  • sed 并不是真正为处理变量扩展而设计的。
  • @RamanSailopal 哦,我不能解决这个问题吗?
  • 请尝试向我们提供minimal reproducible example,我猜这可能是使用a 命令和变量的单个sed 调用。向我们展示您的输入和所需的输出。
  • @TomFenech 谢谢!我用示例输入和输出修改了描述,并从脚本中剪切了一些文件。
  • 我想的是更像var=foo 然后在插入foo 之前和之后显示文件示例。

标签: bash shell sed scripting


【解决方案1】:

这是因为\后跟换行符表示要加入以下行,以避免转义:\\

sed  "/${logs[$i]}$/a\\
        ${send_logs[$i]} \\
        " $syslog_conf_file

【讨论】:

  • 我不太确定您在解释中的意思,但基本上在双引号内,您需要使用 \\ 以便 sed 看到单个 \
  • @TomFenech 我的意思是,当行尾有一个反斜杠字符时,换行符将被删除(单引号内除外)
  • 为什么你认为它被删除了?
  • 因为这是 read 的工作原理,一个简单的例子可以演示,也可以参考:gnu.org/software/bash/manual/html_node/…
  • 感谢您的链接。据我了解,它说换行符之前的反斜杠已被删除,但它并没有说明换行符会发生什么。
猜你喜欢
  • 2020-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多