선행 탭 문자 없이 여러 줄 정규식 추출

선행 탭 문자 없이 여러 줄 정규식 추출

일부 코드 추출 스크립트를 구성하려고 했지만 제대로 작동하지 않습니다.

내 목표는 디렉터리의 모든 .txt 파일을 확인하는 것입니다. 탭으로 시작하지 않고 cat.*.c를 포함하는 줄이 포함된 경우 해당 줄(제외)에서 }(포함)로 시작하는 마지막 줄까지 줄을 추출하여 동일한 이름의 파일에 저장합니다. .c 확장자를 제외하고 소스로 사용됩니다.

그것을 찾으려는 나의 첫 번째 시도는 다음과 같습니다.

find . -name "*.txt" -print0 | xargs -0 awk '/[^ \t]cat .*.c/,/[^ \t]}/'

이유는 모르겠지만 탭 일치가 작동하지 않습니다.

분명히 나는 ​​더 많은 일을 해야 합니다. 파일을 반복하면서 find파일 디렉터리와 이름을 가져와야 합니다.

filename=$(basename "$1")
filename="${filename%.*}"
dirname=`dirname "$1"

하지만 먼저 내가 원하는 텍스트를 얻는 방법을 알아내야 합니다. awk작업에 적합한 도구 인가요 ? sed/가 grep더 나은 선택일까요?

어떤 도움이라도 대단히 감사하겠습니다! 감사합니다!

PS 주변을 검색해 보았지만 탭 문제는 저에게만 국한된 것 같습니다. 또한 불균형 매칭(이전/포함)은 거의 사용되지 않는 것 같습니다...

답변1

내가 올바르게 이해했다면 다음과 같은 것을 원할 것입니다.

awk '
  NR==1, !/^[ \t]/ && /cat.*\.c/ {next}
  {a = a $0 "\n"}
  /^\}/ {printf "%s", a; a=""}'

그리고 find와 통합되었습니다.

find . -name '*.txt' -type f -exec awk '
  FNR == 1 {
    if (newfile != "") close(newfile)
    newfile = FILENAME
    sub(/\.txt$/, ".c", newfile)
    a = ""
  }
  FNR==1, !/^[ \t]/ && /cat.*\.c/ {next}
  {a = a $0 "\n"}
  /^\}/ {printf "%s", a > newfile; a = ""}' {} +

답변2

마침내 sch의 답변을 연구할 시간이 생겼습니다. 다른 사람이 유용하다고 생각할 경우를 대비해 내 "최종" 스크립트는 다음과 같습니다.

for i in `find . -name '*.txt' -type f`
do
    awk '
FNR == 1 {
    if (newfile != "") close(newfile)
    newfile = FILENAME
    sub(/\.txt$/, ".c", newfile)
    a = ""
}
FNR==1, !/^[ \t]/ && /cat.*\.c/ {next}
{a = a $0 "\n"}
/^\}/ {printf "%s", a > newfile; a = ""}' $i

    filename=$(basename "$i")
    filename="${filename%.*}"
    dirname=`dirname "$i"`
    cfilename="${dirname}/${filename}.c"
    if [ -f ${cfilename} ]
    then
        echo "Extracted code from: ${dirname}/${filename}.txt"
        gccErrors=`gcc -Wall ${cfilename} -o "${dirname}/${filename}" -lm 2>&1`
        if [ -n "${gccErrors}" ]
        then
            echo ${gccErrors}
            gccErrorFile="${dirname}/${filename}_GCCERRORS.txt"
            if [ -f ${gccErrorFile} ]
            then
                echo "Can't write to \"${gccErrorFile}\" File already exists!"
            else
                echo ${gccErrors} > ${gccErrorFile}
            fi
        fi
    fi
done

관련 정보