ファイルから入力した行を削除するエイリアス関数を作成しようとしています。
function remove_line(){
line_to_remove="'s/^"$1"$//g'"
sed -i $(line_to_remove) my_file
}
例:
remove_line domain.com
このドメインは指定されたファイルから削除する必要があります。
しかし$
正確な説明はないようです。私は何が間違っていましたか?
答え1
あなたの主な質問$(line_to_remove)
はコマンドの置き換えつまり、括弧内のコマンドによって出力されたテキストに置き換えられた式です(line_to_remove
これにより、「コマンドが見つかりません」エラーが発生すると予想されます)。あなたはそれを使用したいかもしれません"$line_to_remove"
。
ただしsed
、代替式にシェル変数を挿入することは、挿入された文字列にあまりにも多くの条件を指定するため、理想的ではありません(有効な正規表現でなければならず、次のものを/
含めることはできません)。
grep
代わりに、標準出力に結果を使用して書き込み、一時ファイルに書き込む、または正常に実行した後に元のファイルを置き換えることをお勧めします。または(GNU moreutilsパッケージから)元のファイルを上書きすることgrep
もできます。sponge
remove_lines () {
grep -v -Fx -e "$1" my_file | sponge my_file
}
ここで使用されるオプションは、grep
関数の最初の引数で指定された行が正規表現ではなくそのまま使用され、最初から最後まで行が一致し、入力から一致する行が削除されることを保証します。
いいえsponge
:
remove_lines () {
tmpfile=$(mktemp)
grep -v -Fx -e "$1" my_file >"$tmpfile" && mv "$tmpfile" my_file
rm -f "$tmpfile"
}
mv
成功した場合にのみ実行され、失敗するgrep
と一時ファイルは削除されますrm -f
。
個人的には、私はおそらく次のように関数を書くでしょう。
remove_lines () {
grep -v -Fx -e "$1"
}
これにより、ユーザーは次のように使用できます。
remove_lines "my line" <my_file | sponge my_file
some-command | remove_lines "bumble bee" | other-command
これにより、関数がフィルタとして機能します。ただ注釈に書かれているようにしてくださいつまり、入力から行を削除し、入力がどこから来たのか、どこに行くのか気にしません。