특정 문자열을 일치시킨 후에만 파일 내부에 타임스탬프를 추가하고 싶습니다.
타임스탬프 형식: 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)
.