変数を使ってみました(行位置)をファイルを「切り取り」の引数として使用しましたが、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
。この場合、このフォームを直接実行できるため、その理由はわかりませんsed
。sed
コマンドが複数のアドレスを使用する場合、コマンドは行番号、正規表現、またはこれらの形式の組み合わせのアドレスを使用します。
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"