我一直在尝试将一些代码提取脚本组合在一起,但我无法让它工作。
我的目标是检查目录中的所有 .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