특정 문자열을 일치시킨 후 파일에 타임스탬프(월_연도)를 추가하는 방법은 무엇입니까?

특정 문자열을 일치시킨 후 파일에 타임스탬프(월_연도)를 추가하는 방법은 무엇입니까?

특정 문자열을 일치시킨 후에만 파일 내부에 타임스탬프를 추가하고 싶습니다.

타임스탬프 형식: 03_2016

파일에는 "$channel_name 정책"문자열, 이 문자열을 다음으로 바꾸고 싶습니다."$channel_name 정책_03_2016"

파일 내용에 타임스탬프를 추가하고 싶습니다.

package_path=/LSB/Packages/Policy
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy
package_path=/LSB/Packages/Unapproved/$channel_name

필수 파일 형식:

package_path=/LSB/Packages/Policy
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy_03_2016
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy 
package_path=/LSB/Packages/Unapproved/$channel_name

이제 다음 명령을 사용하여 파일에 타임스탬프를 추가합니다.

sed -i "s/$channel_name Policy/$channel_name Policy_$(date +%m_%Y)/g" filename

하지만 이 명령은 다음 항목을 모두 대체합니다.정책그리고정책_03_2016 이와 같이:

package_path=/LSB/Packages/Policy_03_2016
channel_path=/LSB/Channels/$parent_channel_name/$channel_name Policy_03_2016
erratum_path=/LSB/Errata/$erratum_type Policies/$erratum_name
errata_path =/LSB/Errata/$parent_channel_name/$channel_name Advisory Roll-Up Policy_03_2016
package_path=/LSB/Packages/Unapproved/$channel_name 

이 문제에 대한 해결책이 있습니까?

답변1

$매개변수 확장(예: $var, $1, $channel_name), 산술 확장(예: $((1+1))) 및 명령 대체(예 $(cmd):실제로 여기서 사용됨).

$또한 /를 사용하여 활성화 s/regex/replacement/ sed하지 않는 한 "주제의 끝"을 의미하는 연산자이기 때문에 정규식(예: 명령 왼쪽)의 특수 기능입니다.-E-r확장하다$정규식 자체의 끝이나 뒤 \)(또는 지원되는 경우) 를 제외하고는 특별하지 않은 정규식입니다 \|. 그래도 그것으로부터 도망치는 것은 좋은 습관이다.

sed셸과 큰따옴표 안의 정규 표현식은 모두 \문자의 특별한 의미를 제거하는 이스케이프 연산자를 지원합니다. \두 경우 모두 자체적으로 탈출하는 것도 가능합니다.

여기서는 다음과 같이 할 수 있습니다.

sed -i "s/\\\$channel_name Policy/\$channel_name Policy_$(date +%m_%Y)/g" filename

즉, \\\$~에게탈출하다 \다시 탈출하는 곳으로 전달되기 위해 자체와 \$쉘 . 명령의 대체 부분이 특별하지 않기 때문에 오른쪽이면 충분합니다.\$sed\$\$$s/regexp/replacement/

POSIX는 아니지만 이것은 내가 아는 모든 셸에서도 작동합니다.

sed -i "s/[$]channel_name Policy/&_$(date +%m_%Y)/g" filename

[$]또 다른 방법이다탈출하다 $정규식에서. [...]성냥놓다하나만 포함하는 문자: $. POSIX는 shell 을 지정하지 않지만 [$]그대로 유지되지 않는 쉘은 없습니다. 그러나 [\$]POSIX 규격을 준수하려면 셸 코드가 필요합니다.

우리는 또한 &이를 대신하여 표현하기 위해 사용합니다.정규식과 일치하는 문자열.

또 다른 옵션은 다음을 사용하는 것입니다.아포스트로피(특별하지 않은) 대부분의 문자열 $과 명령 대체의 $경우 꼭 필요한 것은 아니지만 큰따옴표가 정규식에서 여전히 이스케이프됩니다.

sed -i 's/\$channel_name Policy/&_'"$(date +%m_%Y)/g" filename

큰따옴표를 사용해야 합니다 $(...). 그렇지 않으면 분할+글로브가 적용됩니다.

답변2

"don_crissti"가 언급했듯이 달러 기호를 이스케이프 처리해야 합니다. 그렇지 않으면 변수 내용을 가져오려고 시도합니다(귀하의 경우 null).

또는 파일에도 슬래시가 있으므로 "/" 이외의 다른 구분 기호를 사용하는 것이 더 안전합니다. 그러나 대체 표현식에 사용하지 않는 한 이는 문제가 되지 않습니다.

내 작업 솔루션:

sed -i 's!\$channel_name Policy!&_'$(date +%m_%Y)'!g' policies.txt

&두 번째로 가능한 개선 방법은 검색된 표현식과 일부 추가 콘텐츠가 정확히 일치하므로 대체 항목에 를 사용하는 것입니다 .

셋째, 내 테스트에서는 명령이 표현식 $(date +%m_%Y)외부에 있을 때만 sed(작은따옴표로 묶음) 작동하도록 할 수 있었습니다.

GNU sed나는 또한 (위의 줄)과 with를 시도했지만 OSX sed둘 다 올바르게 해석하지 못했습니다 $(command).

관련 정보