누군가 여기에서 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

두 번째 파일의 입력을 변경하기 위해 이 파일을 빌려왔습니다 /home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist. 특히 extra_controls_inlist2_nameextra_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가 텍스트를 찾고 바꾸는 스트림 편집기라는 것을 알고 있으며 이것이 두 번째 파일에 대한 나의 목표입니다. 그러나 -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. 이 플래그는 대소문자를 구분하지 않는 표현식 일치를 만듭니다. 바라보다GNU sed문서이에.

  5. 주변의 이상한 인용문 $controls:

    • 표현식은 sed작은따옴표로 묶인 문자열로 제공됩니다. 작은따옴표로 묶인 문자열이므로 변수가 확장되지 않습니다. 변수 값을 삽입하려면 먼저 작은따옴표로 묶인 문자열을 종료해야 합니다. 이것이 첫 번째입니다 '.
    • 그런 다음 코드 작성자는 문자 그대로 작은따옴표를 삽입하려고 했습니다. 이를 위해 그들은 다음과 같이 인용합니다 "'". 여기에서도 사용 가능합니다 \'.
    • 그런 다음 어떤 이유로든 그 뒤에는 작은따옴표 빈 문자열이 옵니다.''
    • 그런 다음 (인용되지 않은) 값이 옵니다 $controls.
    • 또 다른 빈 큰따옴표 문자열인 "".
    • 다른 인용문에 대한 작은따옴표, "'".
    • 그런 다음 표현식은 sed작은따옴표로 묶인 문자열로 계속됩니다.

다음과 같은 인용문에는 몇 가지 문제가 있습니다 $controls.

  1. 두 개의 빈 문자열이 있습니다.
  2. 확장은 $controls인용되지 않았습니다.

이러한 문제를 피하는 더 나은 변형은 다음과 같습니다.

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

즉, sed전체 표현식에 큰따옴표로 묶인 문자열을 사용하면 됩니다(또한 올바르게 인용하면 $MESA_INLIST내보내기 btw를 사용할 필요가 없습니다 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"

또 다른 최적화는 두 호출을 sed하나로 결합하는 것입니다.

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

관련 정보