Bash 循环以按文件计算 php 个标签
Bash loop to count php tags by file
我想要一个 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
也可以转换成一行命令吗?
你写的是(或多或少)你想要的脚本。只需修复分配。将内容写入文件,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
作为开始标签。
任何时候你在 shell 中写一个循环只是为了操作文本,你的方法都是错误的。在这种情况下,您拥有的脚本和您选择的答案都将非常低效和脆弱,并且会产生奇怪的意外输出 and/or 语法错误,具体取决于您 运行 它们所在的目录的内容。
用于处理文本的 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 个进程,而不是 shell 脚本每个文件 4 个进程,因此效率会提高几个数量级,并且适用于任何文件名,包括那些包含白色的文件名space 甚至换行符。
请注意,就像您的 shell 循环的行为一样,上述内容实际上并没有检测到 bad.php 文件中的不匹配,因为缺少一个打开和 1 个缺少关闭。幸运的是,它也很容易增强,例如,告诉您 open/close 行不匹配的行号和内容,并在它们出现时报告它们:
$ 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 = [=13=]
}
/\?>/ {
if (++end > beg) {
print "Warning:", FILENAME, "missing open for the close at line", FNR, [=13=]
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>'; ?>
顺便说一句,我使用 beg
/end
作为上面的 var 名称而不是 open
/close
因为 close()
是一个 awk 函数名称。
我想要一个 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
也可以转换成一行命令吗?
你写的是(或多或少)你想要的脚本。只需修复分配。将内容写入文件,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
作为开始标签。
任何时候你在 shell 中写一个循环只是为了操作文本,你的方法都是错误的。在这种情况下,您拥有的脚本和您选择的答案都将非常低效和脆弱,并且会产生奇怪的意外输出 and/or 语法错误,具体取决于您 运行 它们所在的目录的内容。
用于处理文本的 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 个进程,而不是 shell 脚本每个文件 4 个进程,因此效率会提高几个数量级,并且适用于任何文件名,包括那些包含白色的文件名space 甚至换行符。
请注意,就像您的 shell 循环的行为一样,上述内容实际上并没有检测到 bad.php 文件中的不匹配,因为缺少一个打开和 1 个缺少关闭。幸运的是,它也很容易增强,例如,告诉您 open/close 行不匹配的行号和内容,并在它们出现时报告它们:
$ 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 = [=13=]
}
/\?>/ {
if (++end > beg) {
print "Warning:", FILENAME, "missing open for the close at line", FNR, [=13=]
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>'; ?>
顺便说一句,我使用 beg
/end
作为上面的 var 名称而不是 open
/close
因为 close()
是一个 awk 函数名称。