提取不带前导制表符的多行正则表达式

提取不带前导制表符的多行正则表达式

我一直在尝试将一些代码提取脚本组合在一起,但我无法让它工作。

我的目标是检查目录中的所有 .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

相关内容