본문 바로가기

리눅스 환경에서는 sed (Stream Editor) 명령어를 사용하여 파일 내의 특정 문자열을 찾아 바꾸는 작업을 할 수 있습니다. 여러분이 원하는 -timescale=1ns/1ps 문자열을 timescale=1ns/1ns로 바꾸고자 할 때, 특정 확장자(.csh)를 가진 파일들에 대하여 이 작업을 적용하려면, find 명령어와 sed를 결합하여 사용할 수 있습니다.

다음은 이를 위한 한 가지 방법을 제시하는 명령어 스크립트 예시입니다:

find . -type f -name "*.csh" -exec sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' {} +

이 명령어는 다음과 같이 작동합니다:

  • find . -type f -name "*.csh": 현재 디렉토리(.)에서 확장자가 .csh인 모든 파일들을 찾습니다.
  • -exec: 찾은 각 파일에 대해 명령어를 실행합니다.
  • sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' {}: sed를 사용해 각 파일({}) 내에서 -timescale=1ns/1ps 문자열을 timescale=1ns/1ns로 변경합니다. -i 옵션은 파일을 직접 수정하라는 의미입니다.
    • s/찾을문자열/바꿀문자열/g: s는 substitute (치환)을 의미하며, g는 global의 약자로, 해당되는 모든 인스턴스를 치환하라는 의미입니다.
  • / 문자는 sed 명령어에서 특별한 의미를 가지므로, 문자열 내에서 /를 사용하고 싶을 때는 \/와 같이 이스케이프 해주어야 합니다.

주의사항: -i 옵션은 파일을 바로 수정하므로, 원본 데이터에 변경을 가하기 전에 반드시 백업을 하시기 바랍니다.

위 명령어를 실행하기 전에 중요한 파일들을 백업하거나, -i 옵션 없이 명령어를 실행해 먼저 어떤 변경이 이루어질지 확인할 수 있습니다. 예를 들어, 다음과 같이 실행할 수 있습니다:

find . -type f -name "*.csh" -exec sed 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' {} +

이렇게 하면 실제로 파일을 수정하지 않고 결과를 출력하기 때문에, 실제 변경 전에 어떤 일이 발생할지 미리 볼 수 있습니다.

질문

sed 구문의 맨 마지막 {} 는 무슨 의미인가요?

sed 명령어에서 맨 마지막에 사용된 {}find 명령어와 함께 -exec 옵션을 사용할 때의 문법에 속합니다, 아닌 sed 자체의 문법 요소가 아닙니다. -exec 옵션을 사용할 때, {}find 명령어에 의해 찾아진 각 파일의 경로와 이름을 대체하는 자리 표시자 역할을 합니다. 즉, find가 찾은 각 파일에 대하여 -exec 뒤에 오는 명령어가 실행되며, 이때 {}가 그 파일의 경로와 이름으로 치환됩니다.

예를 들어, 만약 find . -type f -name "*.csh" 명령이 ./example.csh./test/example2.csh 파일을 찾았다면, -exec sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' {} + 명령어는 실질적으로 다음과 같이 두 번 실행됩니다:

  • 첫 번째 파일에 대하여: sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' ./example.csh
  • 두 번째 파일에 대하여: sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' ./test/example2.csh

여기서 +find 명령어가 -exec를 사용할 때의 효율을 개선하는 데 사용됩니다. {}로 표시된 위치에 여러 파일 이름을 넣을 수 있게 하여, 가능한 경우 한 번에 여러 파일에 대해 sed 명령어를 실행하도록 합니다. 이는 -exec를 각 파일마다 개별적으로 실행하는 대신, 찾아진 여러 파일에 대해 한 번의 sed 호출로 처리할 수 있게 하여 성능을 향상시킵니다.

그럼 + 기호는?

find 명령어에서 -exec 옵션과 함께 사용되는 + 기호는 find가 찾은 모든 파일을 대상으로 명령을 단 한 번만 실행하게 하는 역할을 합니다. 이는 find가 찾은 각 파일에 대해 개별적으로 명령을 실행하는 대신, 가능한 많은 파일 경로를 한 번의 명령 실행에 전달함으로써 효율성을 높이는 방식입니다.

일반적으로 -exec 옵션 뒤에는 ;를 사용하여 명령의 끝을 나타냅니다. 이 경우, find는 찾은 각 파일에 대해 개별적으로 명령을 실행합니다. 예를 들어, 100개의 파일이 있다면, ;를 사용하면 find는 100번의 별도 명령을 실행합니다.

반면에, +를 사용하면 find는 가능한 한 많은 파일 경로를 한 번의 명령 실행에 전달합니다. 이는 특히 많은 수의 파일을 처리할 때 시간과 시스템 리소스를 절약할 수 있습니다. find 명령어는 시스템의 한계와 명령어 호출의 최대 길이 제한 내에서 가능한 많은 파일 경로를 한 번에 처리하려고 시도합니다.

예를 들어, 다음 명령은 찾은 모든 .csh 파일에 대해 한 번의 sed 명령을 실행하여 -timescale=1ns/1ps 문자열을 timescale=1ns/1ns로 변경합니다:

find . -type f -name "*.csh" -exec sed -i 's/-timescale=1ns\/1ps/timescale=1ns\/1ns/g' {} +

여기서 +find가 모든 .csh 파일을 sed 명령어에 한 번에 넘겨주어, sed가 가능한 많은 파일을 한 번의 실행으로 처리하도록 합니다. 이 방식은 처리해야 할 파일의 수가 많을 때 효과적인 성능 개선을 제공합니다.

B로그0간

개발 관련 글과 유용한 정보를 공유하는 공간입니다.