誰かがここでsedコマンドの構文を説明できますか?

誰かがここでsedコマンドの構文を説明できますか?

私はシェルスクリプトを必要とする研究プロジェクトを進めています。プログラミング経験はありますが、経験はほとんどありません。問題のファイルは次のとおりです。

export OMP_NUM_THREADS=12


read controls
#inlist directory
export MESA_INLIST="/home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist"

sed -i -e 's/.*extra_star_job_inlist2_name.*/extra_star_job_inlist2_name = '"'"''$controls"""'"'/i' $MESA_INLIST
sed -i -e 's/.*extra_controls_inlist2_name.*/extra_controls_inlist2_name = '"'"''$controls"""'"'/i' $MESA_INLIST

2番目のファイルの入力を変更するためにこのファイルを借りました/home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist。特に、extra_controls_inlist2_name変数extra_star_job_inlist2_name(等号の右に続く変数)です。

! this is the master inlist that MESA reads when it starts.

! This file tells MESA to go look elsewhere for its configuration
! info. This makes changing between different inlists easier, by
! allowing you to easily change the name of the file that gets read.

&star_job

      read_extra_star_job_inlist1 = .true.
      extra_star_job_inlist1_name = 'inlist_0all'

      read_extra_star_job_inlist2 = .true.
extra_star_job_inlist2_name = 'inlist_3ms'

/ ! end of star_job namelist


&controls

      read_extra_controls_inlist1 = .true.
      extra_controls_inlist1_name = 'inlist_0all'

      read_extra_controls_inlist2 = .true.
extra_controls_inlist2_name = 'inlist_3ms'

/ ! end of controls namelist


&pgstar

/ ! end of pgstar namelist

私はすでにコマンドとその機能についてexportよく知っています。read私はsedがテキストを見つけて置き換えるストリームエディタであることを知っており、これが2番目のファイルの私の目標です。しかし、-i -eこれらのオプションの役割は正確に何ですか?周りに引用文がなぜこんなにたくさんありますか$controls$? sedコマンドでtheとtheはどういう/.*意味ですか?/iオンラインで予備検索しようとしましたが、適切な回答が見つかりませんでした。

答え1

  1. -e「次のコマンドライン引数はsed式です」を意味します。
  2. -i「こうして編集してください」という意味です。所定の位置につまり、元のファイルを変更します。」このオプションは非標準であり、sed異なるUnixシステムで異なる実装間で移動すると混乱を招く可能性があります。sed -i(所定の位置で編集)を使用して移植性を達成するには?
  3. /.*置換するテキストに一致する正規表現の始まりです。実際には、(代替)コマンドの区切り文字で正規表現/の始まりです。それ自体は「任意の文字数と一致」を意味します。s///sed.*extra_star_job_inlist2_name.*.*

    .*式の終わりにも表示され.*extra_star_job_inlist2_name.*、その効果は文字列を含むすべての行が完全に置き換えられることです(つまり、置換はその行の文字列extra_star_job_inlist2_nameにのみ影響しません)。extra_star_job_inlist2_name

  4. /i繰り返しますが、これは/コマンドの区切り記号であり、その後にs///sedバナーコマンドのためにs///。このフラグは非標準で、GNUスタイルでのみ使用されますsed。このフラグは、大文字と小文字を区別しない式の一致を作成します。バラよりGNUsedドキュメントこれに。

  5. 周りの奇妙な引用$controls

    • 式はsed一重引用符で囲まれた文字列として提供されます。一重引用符で囲まれた文字列なので、変数は拡張されません。変数値を挿入する前に、一重引用符で囲まれた文字列を終了する必要があります。これが最初です'
    • その後、コードライターは文字通り一重引用符を挿入しようとしました。この目的のために、彼らは次のように引用します"'"。ここでも利用可能です\'
    • その後、何らかの理由で、その後に一重引用符の空の文字列が続きます。''
    • その後、(引用されていない)値が続きます$controls
    • 別の空の二重引用符文字列""
    • 他の引用のための一重引用符、"'"
    • その後、式はsed一重引用符で囲まれた文字列に続きます。

次の引用にはいくつかの問題があります$controls

  1. 2つの空の文字列があります。
  2. 拡張は$controls引用されていません。

これらの問題を回避するより良い変形は次のとおりです。

sed -i -e "s/.*extra_star_job_inlist2_name.*/extra_star_job_inlist2_name = '$controls'/i" "$MESA_INLIST"

つまり、sed式全体に二重引用符で囲まれた文字列を使用できます(また、正しく引用した場合はエクスポート$MESA_INLISTbtwを使用する必要はありませんexport)。これはsed、式自体にバックスラッシュや文字が含まれていない限り機能します(これらと$エスケープする必要があります)。\\\$

または少し短くするには、キャプチャグループを使用して代替テキストで繰り返す文字列をキャプチャし、

sed -i -e "s/.*\(extra_star_job_inlist2_name\).*/\1 = '$controls'/i" "$MESA_INLIST"

(他のコマンドもsed似ています。)

式の前に一重引用符を使用するには、sed次のようにします。

sed -i -e 's/.*\(extra_star_job_inlist2_name\).*/\1 = '"'$controls'"'/i' "$MESA_INLIST"

もう1つの最適化は、2つの呼び出しをsed1つにまとめることです。

sed -i -e "s/.*\(extra_star_job_inlist2_name\).*/\1 = '$controls'/i" \
       -e "s/.*\(extra_controls_inlist2_name\).*/\1 = '$controls'/i" "$MESA_INLIST"

関連情報