行を読み、条件に応じて行の先頭にポンド記号(#)を追加します。

行を読み、条件に応じて行の先頭にポンド記号(#)を追加します。

複数行のテキストを含むファイルを読み取り、その行でコマンドを実行する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 OKコードecho FAIL行を変更するだけです。頑張ったこの回答しかし、最終的にすべての行が削除されます。私はそれをしたくないファイルに失敗した行を維持したいと思います。

試してみましsedたが、あまり効果がないようです。

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

これを行う方法はありますか?

PS:LinuxとMacの端末、特にMac zshのbashと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コードで評価されます。これらの行で特定または特定の機能を使用している場合は、その機能をまたはshに置き換えますbashzshbashzsh

ここではファイルを生成し、最後にfile.new名前を変更します。 (GNU)または(FreeBSD / macOS)fileもある程度同じです。通常、特定のファイルの読み込み中にそのファイルに簡単に書き込むことはできません。sed -ised -i ''

答え2

sed [command] file > fileあなたが見つけたように、あなたの意志を使うことはあなたが望むことをしません。リダイレクトすると、内容が消去され、出力fileに置き換えられますsed

あなたがしなければならないのは、組み込みsed関数を使用してファイルをその場で変更することです。

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

関連情報