複数行のテキストを含むファイルを読み取り、その行でコマンドを実行する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
に置き換えますbash
。zsh
bash
zsh
ここではファイルを生成し、最後にfile.new
名前を変更します。 (GNU)または(FreeBSD / macOS)file
もある程度同じです。通常、特定のファイルの読み込み中にそのファイルに簡単に書き込むことはできません。sed -i
sed -i ''
答え2
sed [command] file > file
あなたが見つけたように、あなたの意志を使うことはあなたが望むことをしません。リダイレクトすると、内容が消去され、出力file
に置き換えられますsed
。
あなたがしなければならないのは、組み込みsed
関数を使用してファイルをその場で変更することです。
sed --in-place "$COUNTs/^/#/" file