Bash循环按文件计算php标签

时间:2015-05-21 21:18:19

标签: php bash awk grep

我想要一个bash脚本来计算找到孤立标签的次数。我认为它会像

我用来计算出现次数的命令是grep -o"

也许

for i in *.php; do
    open = grep -o "<?php" $i | wc -l
    close = grep -o "?>" $i | wc -l
    echo $i open close
done

file1.php 5 5
file2.php 4 5

也可以转换成一行命令吗?

2 个答案:

答案 0 :(得分:1)

您所写的内容(或多或少)是您想要的脚本。只需修复作业即可。将内容写入文件chmod +x文件并瞧。

#!/bin/bash
for i in *.php
do
    open=$(grep -o "<?php" $i | wc -l)
    close=$(grep -o "?>" $i | wc -l)
    echo $i open close
done

请务必使用<?php作为开头标记。

答案 1 :(得分:1)

任何时候你在shell中编写循环只是为了操作文本你都有错误的方法。在这种情况下,您拥有的脚本和您选择的答案都将非常低效和脆弱,并将产生奇怪的意外输出和/或语法错误,具体取决于您运行它们的目录的内容。

用于操作文本的UNIX工具是awk - 只需使用它(在这种情况下我使用GNU awk作为ENDFILE):

$ cat good.php
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo '<p>Hello World</p>'; ?>
 <?php echo '<p>Goodbye Cruel World</p>'; ?>
 </body>
</html>

$ cat bad.php
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo '<p>Hello World</p>';
 <?php echo '<p>Goodbye Cruel World</p>'; ?>
 <?php echo '<p>Hello Again World</p>'; ?>
 echo '<p>Goodbye Again Cruel World</p>'; ?>
 </body>
</html>

awk '/<\?php/{++beg} /\?>/{++end} ENDFILE{print FILENAME, beg, end; beg=end=0}' *.php
bad.php 3 3
good.php 2 2

以上为所有文件使用1个进程总计,而不是每个文件4个用于shell脚本,因此它的效率将提高几个数量级,并且它适用于任何文件名,包括那些包含空格或甚至换行符的文件名。

请注意,就像你的shell循环一样,上面的实际上并没有检测到bad.php文件中的不匹配,因为有一个缺失打开和一个缺失关闭。幸运的是,它也很容易增强,比如告诉你开/关线不匹配的行数和内容,并在发生时报告它们:

$ awk '
FNR==1 { beg=end=0 }
/<\?php/ {
    if (beg++ > end) {
        print "Warning:", FILENAME, "missing close for the open at line", begFnr, begRec
        beg--
    }
    begFnr = FNR
    begRec = $0
}
/\?>/ {
    if (++end > beg) {
        print "Warning:", FILENAME, "missing open for the close at line", FNR, $0
        end--
    }
}
ENDFILE {
    if (beg > end) {
        print "Warning:", FILENAME, "missing close for the open at line", begFnr, begRec
    }
}
' *.php
Warning: bad.php missing close for the open at line 6  <?php echo '<p>Hello World</p>';
Warning: bad.php missing open for the close at line 9  echo '<p>Goodbye Again Cruel World</p>'; ?>

BTW我使用beg / end作为上面的var名称,而不是open / close,因为close()是一个awk函数名。