【问题标题】:sed command throwing error in bash scriptsed 命令在 bash 脚本中引发错误
【发布时间】:2024-01-02 09:13:02
【问题描述】:

我有一个简单的 Bash shell 脚本来遍历目录中的每个文件,并检查版权信息是否位于文件顶部。 如果没有,应该添加它。


当我尝试在 sed 命令中使用变量时,脚本出错。我查看了其他类似的问题并尝试了双引号“”,我尝试使用不同的运算符但仍然找不到解决方案。有人可以指出我做错了什么吗?

Msg='/*------------------------------------------------------------------------------
*******************************************************************************
* Copyright message here
*******************************************************************************
*----------------------------------------------------------------------------*/'

for file in * 
  do
    if grep -Fxq "$Msg" $file
      then
        echo Marvel Message already exist: $file
    else
      if test -f "$file" 
        then
         echo "Adding Message to file: $file"
         sed -i "1s/^/${Msg}\n/" $file
      fi
    fi
done

【问题讨论】:

  • 您需要使用不包含在变量中的分隔符,即不是/
  • 我已尝试将分隔符设置为 |,就像在 sed -i "1s|^|${Msg}\n|" $file 中一样,但仍然存在问题
  • 看看sed replace with variable with multiple lines。在那里你看到你应该用sed -i "1s/^/${Msg//$'\n'/\\n}\n/" $file替换你的sed
  • 不,不,不,不。根本不要为此使用 sed。只需这样做:{ echo "$Msg"; cat "$file"; } > $file.tmp; mv $file.tmp $file 如果您愿意,可以添加一些用于清理的陷阱,不要再自欺欺人地认为sed -i 会神奇地保护您免于意外将 tmp 文件留在文件系统上。

标签: bash shell sh ubuntu-16.04


【解决方案1】:

我不会为此使用 sed。我会使用 ed:

ed "$file" <<END
1i
$Msg
.
wq
END

或者,使用 moreutils 包中的sponge

{ echo "$Msg"; cat "$file"; } | sponge "$file"

【讨论】:

  • 我最终使用了管道海绵,但也使用了上面提到的@William Pursell 方法。谢谢大家
【解决方案2】:

只需像这样使用 marge 即可,这里使用 echo "$Msg" > tmp.txt 创建一个文件,其中 $Msg 作为 tmp 文件的标题。并使用cat $file &gt;&gt; tmp.txt 合并文件。

for file in * 
do
if grep -Fxq "$Msg" "$file"
  then
    echo Marvel Message already exist: "$file"
else
  if test -f "$file" 
    then
     echo "Adding Message to file: $file"
     #sed -i "1s/^/${Msg}\n/" $file
     echo "$Msg" > tmp.txt
     cat "$file" >> tmp.txt
     mv tmp.txt "$file"
   fi
 fi
done

希望这会对你有所帮助。

【讨论】: