先行タブ文字なしで複数行正規表現を抽出する

先行タブ文字なしで複数行正規表現を抽出する

いくつかのコード抽出スクリプトを設定しようとしましたが、正常に動作しませんでした。

私の目標は、ディレクトリ内のすべての.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

関連情報