事前作成された sed 文字列が文字列を正しく解釈しません。

事前作成された sed 文字列が文字列を正しく解釈しません。

私のコードは、2つの異なるファイルが同じファイル内の行番号を見つけ、そのファイルの1つからその行番号を除くすべての行を削除するように設計されています。このために、sedで実行したい事前に作成されたsed文字列を作成しましたが、エラーが発生します。

sed: -e expression #1, char 3: unknown command: `;'

私の事前作成されたsed文字列は次のとおりです。

echo ${_sedstr}
1;2;7;11;12;13;15;17;22!d

私の意図は、sedコマンドでこの変数を使用して、文字列の行を除いて$ {_edit}ファイルのすべての行を削除することです。

sed -i.bak -e ${_sedstr} ${_edit} 

${_sedstr}の周りに一重引用符/二重引用符を配置し、バックスラッシュ「\」で引用符をエスケープするすべての組み合わせを試しましたが、コードが期待どおりに実行されるのにまだ問題があるようです。


私が達成したいものの例は次のような$ {_edit}です:

hello
my
name
is
John
Doe

式を使ってsed -i.bak -e '1;2;4!d' ${_edit}ファイルを次に出力したいと思います。

hello
my
is

1、2、4を除くすべての行を削除します。

ベストアンサー1

これは正しい構文ではありませんsed

おそらくsed '1d;2d;7d'そうではありません。sed '1;2;7d'

1、2、7を除くすべてのコマンドを削除するには、次のようにしますsed -e 1b -e 2b -e 7b -e d(portable / POSIXlyを使用してコマンドを;区切ることはできませんが、b改行文字は使用できます)。

だから:

sed_script='1d;2d;7d'
sed -i.back -e "$sed_script" -- "$_edit"

または:

sed_script='
  1b
  2b
  7b
  d
'
sed -i.back -e "$sed_script" -- "$_edit"

パラメータ拡張を引用する必要があります。バラよりいつ二重引用符が必要ですか?。そして--オプションの区切り記号を忘れないでください。ただ、あなたはここでこれをcmd -- "$arg"したくありません。cmd "$option_or_arg"

保持/削除する行が多い場合は、GNUを使用して次のことをawk使用できます。

LINES_TO_KEEP='1;2;7;...' gawk -i /usr/share/awk/inplace.awk -e '
  BEGIN {
    split(ENVIRON["LINES_TO_KEEP"], a, ";")
    for (i in a) keep[a[i]]
  }
  FNR in keep' -E /dev/null "$_edit"

(これはという名前のファイルでは機能しません。代わりに使用する必要が-あります。)_edit=./-_edit=-

使用しないでください-i inplace現在の作業ディレクトリから最初に拡張機能をgawkロードしようとすると、誰かがそのディレクトリにマルウェアを植えた可能性があります。システムに付属の拡張プログラムのパスは異なる場合があります。出力を参照してください。inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

おすすめ記事