我想要一个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
也可以转换成一行命令吗?
答案 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函数名。