sed - 行位置への変数

sed - 行位置への変数

変数を使ってみました(行位置)をファイルを「切り取り」の引数として使用しましたが、sedコマンドでエラーが発生しました。

これは私のコードです。

START=$(grep -n "pattern1" $FILE | cut -f1 | sed 's/:.*$//g')
END=$(grep -n "pattern2" $FILE | cut -f1 | sed 's/:.*$//g')
sed -n '${START},${END}p' $FILE > temp; # error here
# sed: -e expression #1, char 3: unknown command: `S'

しかし、数字を使うときはうまくいきます。

sed -n '28,63p' $FILE > temp;

いくつかのエスケープを適用する必要があるようですが、私は知りません。どんな提案がありますか?とても感謝しています!

答え1

STARTコードの主な問題は、シェルが一重引用符で囲まれた文字列として変数を拡張すると予想していることです。ENDシェルはこれを決して行いません。これは、単一引用符と二重引用符文字列の主な違いの1つです。

代わりに、式に二重引用符で囲まれた文字列を使用してくださいsed

しかし、両方のパイプがそれぞれ行番号を返すと予想しているようですgrep。この場合、このフォームを直接実行できるため、その理由はわかりませんsedsedコマンドが複数のアドレスを使用する場合、コマンドは行番号、正規表現、またはこれらの形式の組み合わせのアドレスを使用します。

sed -n '/pattern1/,/pattern2/ p' "$FILE" >temp

または

sed '/pattern1/,/pattern2/ !d' "$FILE" >temp

おそらくgrepパイプを維持してはいけませんが、行番号を直接返すことで減らすことができることを追加することですsed

start=$( sed -n '/pattern1/ { =; q; }' )

上記は、パターンと一致する最初の行の行番号を提供しますpattern1=現在のライン番号を出力する命令です。

答え2

説明したように二重引用符に変更する必要がありますが、ファイルにパターンが2倍以上あると、元のスクリプトも破損します。上記の解決策はうまく機能し、開始/終了パターン間の各行を印刷します。この1行のコードは最初の項目のみを印刷します。

    sed -n '/pattern1/{:loop;p;/pattern2/q;N;s/.*\n//;b loop};' "$file"

関連情報