grep을 사용하여 올바른 줄을 찾고, sed를 사용하여 내용을 변경한 다음 다시 원본 파일에 넣으시겠습니까?

grep을 사용하여 올바른 줄을 찾고, sed를 사용하여 내용을 변경한 다음 다시 원본 파일에 넣으시겠습니까?

파일의 특정 줄에 있는 단일 단어를 변경하려고 하는데 모든 단어를 연결하는 데 문제가 있습니다.

기본적으로 내 파일의 한 줄에는 "firmware_revision"이라는 키워드가 있고 이 줄(및 이 줄만)에서 "test"라는 단어를 "production"이라는 단어로 바꾸고 싶습니다.

그래서 나는 이것을 할 수 있습니다 :

grep 'firmware_revision' myfile.py | sed 's/test/production'

이렇게 하면 원하는 줄을 선택하고 교체를 수행할 수 있지만 이전 줄을 교체하기 위해 이 새 줄을 원본 파일에 넣는 방법을 모르겠습니다. 분명히 파일로 다시 리디렉션할 수 없습니다. 그러면 어떻게 해야 합니까?

임시 파일을 사용하더라도 grep필요한 줄을 얻기 위해 를 사용하면 파일의 다른 모든 데이터가 손실되므로 더 이상 모든 데이터를 임시 파일로 리디렉션한 다음 원본 파일을 임시 파일로 바꿀 수 없습니다.

편집 - 누군가가 추가 정보를 요청했습니다.

다음과 같은 줄로 가득 찬 파일이 있다고 가정해 보겠습니다.

[
  ('key_name1', str, 'value1', 'Description'),
  ('key_name2', str, 'value2', 'Description'),
  ('key_name3', str, 'value3', 'Description'),
  ('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]

이제 "firmware_revision"이 포함된 줄을 찾고 해당 줄에 있는 "test"라는 단어의 모든 인스턴스를 "production"으로 변경하는 스크립트(가급적 한 줄)를 작성하고 싶습니다. "test"라는 단어가 파일의 다른 곳에 있을 수 있으며 해당 위치가 변경되는 것을 원하지 않습니다. 명확성을 위해 위 줄을 다음과 같이 변경하고 싶습니다.

('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')

어떻게 해야 하나요?

답변1

노력하다:

sed -i.bak '/firmware_revision/ s/test/production/' myfile.py

여기서는 /firmware_revision/조건으로 작용합니다. 정규식과 일치하는 작업의 경우 true이고 firmware_revision, 다른 작업의 경우 false입니다. 조건이 true이면 다음 명령이 실행됩니다. 이 경우 명령은 의 첫 번째 발생을 로 바꾸는 대체 명령 test입니다 production.

즉, 명령은 s/test/production/regex 와 일치하는 행에서만 실행됩니다 firmware_revision. 다른 모든 줄은 변경되지 않습니다.

기본적으로 sed는 출력을 표준 출력으로 보냅니다. 그러나 파일을 그 자리에서 변경하려고 합니다. 그래서 이 -i옵션을 추가했습니다. 특히, -i.bak파일을 변경하게 하고 확장자를 .bak.

이 명령이 자신에게 적합하다고 판단하고 백업을 만들지 않고 위험하게 살고 싶다면 GNU sed(Linux)를 사용하여 다음을 사용하십시오.

sed -i '/firmware_revision/ s/test/production/' myfile.py

대조적으로, BSD(OSX)에서는 이 -i옵션에 인수가 있어야 합니다. 백업을 유지하지 않으려면 빈 인수를 제공하십시오. 따라서 다음을 사용하십시오.

sed -i '' '/firmware_revision/ s/test/production/' myfile.py

편집하다

질문 편집에서 OP가 물었습니다.모든나타나는 test내용을 바꾸십시오 production. 이 경우 g대체 명령에 옵션을 추가합니다.글로벌(이 줄의 경우) 교체:

sed -i.bak '/firmware_revision/ s/test/production/g' myfile.py

답변2

sed옵션을 지원하지 않는 이전 시스템의 경우 -i:

TF=$( mktemp -t "${0##*/}"_$$_XXXXXXXX ) && \
trap 'rm -f "$TF"' EXIT HUP INT QUIT TERM && \
sed '/firmware_revision/ s/test/production/' myfile.py >"$TF" && \
mv -f "$TF" myfile.py

관련 정보