redux-saga의 이펙터와 TypeScript inteface naming convention을 일괄 교체하면서 사용한 방법입니다.

아래 스크립트는 macOS에서 작성했습니다.

  • 활용한 grep 옵션
    • -n: 찾은 문자열 위치의 라인 수 표시
    • -r: 재귀적으로 모든 하위 디렉토리 순회
    • -i: 대소문자 구분 안함
    • -l: 검색 결과에서 해당 문자열을 포함한 파일의 경로만 출력
    • --exclude-dir: 디렉토리 제외
    • --exclude: 파일 제외

먼저 brew install gsedgsed를 설치합니다.

문자열 찾기

grep -nri --exclude-dir={.git,.next,node_modules,public,coverage,.idea,.gradle} --exclude={package-lock.json,report.html} 'fork' .

특정 확장자의 파일만 찾고싶은 경우 (예: ts, tsx)

grep -nri --include \*.ts --include \*.tsx --exclude-dir={.git,.next,node_modules,public,coverage,.idea,.gradle} --exclude={package-lock.json,report.html} 'fork' .

문자열 교체하기

fork를 spawn으로 교체합니다.

(주제와 상관없지만.. NextJS로 server side rendering을 할 때는 spawn 이펙터가 아니라 fork 이펙터를 사용해야 합니다.)

grep -rl --exclude-dir={.git,.next,node_modules,public,coverage,.idea,.gradle} --exclude={package-lock.json,report.html} 'fork' . | xargs gsed -i 's/spawn/fork/g'

TypeScript interface naming convention을 변경하면서 작성한 스크립트입니다. 대문자 I로 시작하는 인터페이스 이름들에서 I를 제거했습니다. (예: IProps -> Props)

TARGET_REGEX='I([A-Z])([a-z])([A-Za-z]*)'
REPLACED='$1$2$3'

grep -rl --exclude-dir={.git,.next,node_modules,public,coverage,.idea,.gradle} --exclude={package-lock.json,report.html} -E $TARGET_REGEX . | xargs gsed -i -E "s/$TARGET_REGEX/$REPLACED/g"

파일 이름 변경

node_modules를 제외한 모든 하위 디렉토리 및 파일 이름을 바꿉니다.

TARGET_REGEX='I([A-Z])([a-z])([A-Za-z]*)'
REPLACED='$1$2$3'

find . -path ./node_modules -prune -o -exec rename "s/$TARGET_REGEX/$REPLACED/g" {} +