读取一行,然后根据条件在行首附加井号 (#)

读取一行,然后根据条件在行首附加井号 (#)

我有一个 bash 脚本,它读取具有多行文本的文件并在这些行上执行命令。有时该命令有效,但有时会失败。我想在命令成功运行的文本行和命令失败的行的开头附加井号 (#),它们应该按原样添加,以便可以在下次运行脚本时重试。从 # 开始的行不会被执行。
我当前的脚本看起来像这样 -

COUNT=1
while read -r LINE; do
    if [[ ($LINE != \#*) && !(-z "${LINE// }") ]] ; then
        echo "${LINE}"
        # execute "$LINE"
        if [ $? -eq 0 ]; then
            echo OK # Append pound (#) at the start of the line
        else
            echo FAIL # Keep the line in the source file
        fi
    fi
    COUNT=$(( $COUNT + 1 ))
done < $SRC_FILE

正如您所看到的,条件已经存在,我只需要替换这些条件echo OKecho FAIL代码行即可。我试过这个答案,但它最终删除了所有行,我不希望这样,我想将失败的行保留在文件中。

我尝试使用sed,但它似乎什么也没做 -

sed -n "${COUNT}s/^/#/" $SRC_FILE >> $SRC_FILE

有什么办法可以做到这一点吗?

PS:我想让它在 Linux 和 Mac 终端上的 bash 和 zsh 上运行,尤其是 Mac zsh。

更新:
我尝试了以下命令

sed "${COUNT}s/.*/#&/" $SRC_FILE >$SRC_FILE

它从源文件中删除所有行并将其设为空,但如果我更改输出文件,它会起作用,尽管仅在最后一行添加 # ,因为它仍然从原始源文件中读取。

答案1

你可以这样做:

#! /bin/sh -
src_file=/path/to/file
{
  while read <&3 -r line; do
    case $line in
      ('#'*) ;;
      (*)
         if eval " $line" 3<&- 4>&-; then
           echo OK
           line="# $line"
         else
           echo FAIL
         fi
    esac
    printf '%s\n' "$line" >&4
  done
  mv -- "$src_file.new" "$src_file"
} 3< "$src_file" 4> "$src_file.new"

文件的每一行都将被评估为sh代码。如果这些行使用-特定或-特定功能,请替换shbash或。zshbashzsh

在这里,我们生成一个文件,最后将file.new其重命名。 (GNU) 或(FreeBSD/macOS)file或多或少也是这么做的。通常,您无法在读取给定文件的同时轻松写入该文件。sed -ised -i ''

答案2

sed [command] file > file正如你所发现的,使用意志并不能做你想做的事。重定向会清除 的内容file并将其替换为 的输出sed

您需要做的是使用 的sed内置功能就地修改文件:

sed --in-place "$COUNTs/^/#/" file

相关内容