优化shell和awk脚本


0

我使用shell脚本,awk脚本和find命令的组合来在数百个文件中执行多个文本替换。文件大小在几百字节到20千字节之间变化。

我正在寻找一种方法来加速这个脚本。

我正在使用cygwin。

shell脚本 -

#!/bin/bash

if [ $# = 0 ]; then
 echo "Argument expected"
 exit 1
fi



while [ $# -ge 1 ]
do
   if [ ! -f $1 ]; then
     echo "No such file as $1"
     exit 1
   fi


  awk -f ~/scripts/parse.awk $1  > ${1}.$$

   if [ $? != 0 ]; then
      echo "Something went wrong with the script"
     rm ${1}.$$
      exit 1
   fi
mv ${1}.$$ $1
shift
done

awk脚本(简化) -

#! /usr/bin/awk -f

/HHH.Web/{
    if ( index($0,"Email") == 0)  {
        sub(/HHH.Web/,"HHH.Web.Email");
    }
    printf("%s\r\n",$0); 
    next;
}

命令行

find .  -type f  | xargs ~/scripts/run_parser.sh

Answers:


0

1)您的错误处理存在错误。如果您通过一个xargs传递一组文件,并且一个文件爆炸,则其他后一个文件都不会被处理。例如,如果

~/scripts/run_parser.sh file1 file2 file3 file4

运行,文件2在awk上爆炸,file1运行,但file2,file3和file4都不会运行。我建议使用continue而不是exit 1那里。

2)你正在使用Cygwin,因为模拟,你会有点慢,无法帮助。在Linux上使用相同的工具会更快。

3)如果你可以破解一些perl,我建议看看perl -p -i能做些什么。Perl语法并不比awk更多,你有一个perl和多个awk的实例化。

除非这非常慢,否则我可能会将其归结为仿真问题。除了perl -p hack来克服awk的一些额外的fork / exec之外,我认为在某个地方没有银弹。


谢谢你的建议。顺便说一下,如果文件失败,我希望脚本退出。
bryan

0

这将在不到10秒的时间内通过我的所有数百个文件进行递归。以前,需要15分钟。

find .  -type f | xargs awk -f ~/scripts/awkv2/parse.awk 

awk脚本(简化) -

/HHH.Web/{
    if ( index($0,"Email") == 0)  {
        sub(/HHH.Web/,"HHH.Web.Email");
    }
    printf("%s\r\n",$0);  > FILENAME
    next;
}

但是,如果输入文件大于64kb,则输出文件被截断为大约64kb。

有什么想法吗?


0

它是读取文件的缓冲区大小,更重要的是,您要覆盖原始的FILENAME。一种解决方案是使用

outFile= FILENAME ".fix"
printf("%s\r\n",$0);  > outFile

并有一个单独的传球

mv ${fileName}.fix ${fileName} 

在bash中

我也同意Rich的观点,Cygwin的仿真使它变得更慢。除了Linux,取决于您的组织对非Gnu开源软件的容忍度,您可以尝试使用David Korn的UWIN(Unix for Windows)http://www2.research.att.com/sw/tools/uwin/ 也可以看到http: //en.wikipedia.org/wiki/UWIN

祝好运


感谢您的帮助,我现在在8秒内解析了400个文件,请参阅此主题链接中的
bryan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.