bash를 사용하여 정규식을 사용하여 파일 목록의 "#include" 형식을 다시 지정합니다.

bash를 사용하여 정규식을 사용하여 파일 목록의 "#include" 형식을 다시 지정합니다.

코드 파일에 대해 간단한 루프를 수행하는 다음 코드를 고려해보세요.

#!/bin/bash
dir="."
find $dir -name *.cpp -o -name *.h | while read file; do
    echo "processing: "$file
    # Process file here
done

모든 파일은 다음과 같은 지저분한 포함으로 시작됩니다.

#include<iostream>
#include <vector>
#include"this_is_file1.h"
#include "this_is_file2.h"
#include "This_Is_File3.h"
#include"thisIsFile4.h"
#include "ThisIsFile5.h"
#include"dir/thisIsFile6.h"
#include "dir/ThisIsFile7.h"
#include "dir/ThisIsFile8.txx"
#include "dir/ThisIsFILe9.txx"

이렇게 변환하고(기존 파일을 덮어쓰고 싶습니다)

#include <iostream>
#include <vector>
#include "this_is_file1.h"
#include "this_is_file2.h"
#include "this_is_file3.h"
#include "this_is_file4.h"
#include "this_is_file5.h"
#include "this_is_file6.h"
#include "this_is_file7.h"
#include "this_is_file8.txx"
#include "this_is_file9.txx"

더 형식적으로:

  • 포함과 파일 이름 사이에는 정확히 하나의 공백이 있어야 합니다.
  • 대문자가 있어서는 안 되며, 파일 이름의 시작 부분이 아닌 이상 연속된 대문자로 대체된 각 문자열 앞에 밑줄이 와야 합니다.
  • 디렉터리 이름이 없어야 합니다.

Bash로 이를 수행하는 방법은 무엇입니까?

답변1

다음 sed 스크립트가 이 작업을 수행해야 합니다.

s/\(#include\) *\([^ ]\+\)/\1 \2/

/^#include "/ {
    s/".*\//"/
    s/"\(.\)/"\l\1/g
    s/\([^A-Z]\)\([A-Z]\)/\1_\l\2/g
    s/_\+/_/g
}

다음 명령을 실행하여 파일에 적용할 수 있습니다.

sed -i.bak -f fix.sed input...

(이는 위의 스크립트가 호출되고 fix.sed나중에 원하는 수의 파일을 인수로 제공할 수 있다고 가정합니다. .bak백업을 생성하지 않으려면 삭제하십시오.)

첫 번째 sed 대체 표현식은 비어 #include있을 수 있는 공백( \ *)과 실행을 일치시키고 해당 실행을 단일 공백으로 대체합니다. 또한 [^ ]\+줄의 나머지 부분( )을 소문자로 변환합니다( 사용 \l).

다음 네 개의 sed 표현식(모두 로 시작하는 줄에만 적용됨 #include ")은 다음을 수행합니다.

  1. 경로 이름을 제거합니다(마지막 슬래시까지의 모든 항목).

  2. 따옴표 사이의 첫 번째 문자를 소문자로 변환합니다.

  3. 각 대문자 그룹의 시작 부분에 밑줄을 삽입하고 그룹의 첫 번째 문자를 소문자로 변환합니다.

  4. 이전 단계에서 삽입되었을 수 있는 밑줄을 돌출시킵니다.

완벽하지는 않지만 예제 입력을 예상대로 변환합니다.

답변2

다음과 같은 것을 사용하여 찾을 수 있습니다스타일코드의 형식을 깔끔하게 지정하고 단순한 줄 이상의 내용을 수정하세요 #include.

코드 있는 그대로에는 문제가 없지만 파일 이름에 공백이나 이상한 내용이 없으면 다음을 사용할 수도 있습니다 find.

astyle --style=allman -A1 --indent=spaces=4  \
   --break-blocks --pad-oper --pad-header --unpad-paren \
   --max-code-length=200 \
   $(find . -name '*.cpp' -print) $(find . -name '*.h' -print)

답변3

perl -i.bak -pe '
   if( s!(#include) *(["<])(.*/)?!$1 $2!){  ## if is a include line
        s/(?<=[a-z])(?=[A-Z])/_/g;          ##   insert CamelCase "_"
        tr/A-Z/a-z/ }'   file               ##   lowercase ids

관련 정보