试试这个。尽管如此,在评论和文字方面却忽略了大括号,因为David Gelhar警告过。它只找到并删除第一次出现的“@ForTestingOnly”块(假设只有一个)。
#!/bin/bash
find . -maxdepth 1 | while read -r file
do
open=0 close=0
# start=$(sed -n '/@ForTestingOnly/{=;q}' "$file")
while read -r line
do
case $line in
*{*) ((open++)) ;;
*}*) ((close++));;
'') : ;; # skip blank lines
*) # these lines contain the line number that the sed "=" command printed
if ((open == close))
then
break
fi
;;
esac
# split braces onto separate lines dropping all other chars
# print the line number once per line that contains either { or }
# done < <(sed -n "$start,$ { /[{}]/ s/\([{}]\)/\1\n/g;ta;b;:a;p;=}" "$file")
done < <(sed -n "/@ForTestingOnly/,$ { /[{}]/ s/\([{}]\)/\1\n/g;ta;b;:a;p;=}" "$file")
end=$line
# sed -i "${start},${end}d" "$file"
sed -i "/@ForTestingOnly/,${end}d" "$file"
done
编辑:删除一个呼叫sed
(注释掉和更换几行)。
编辑2:
这里的主要sed
线的故障:
sed -n "/@ForTestingOnly/,$ { /[{}]/ s/\([{}]\)/\1\n/g;ta;b;:a;p;=}" "$file"
-n
- 只有明确要求
/@ForTestingOnly/,$
当打印线 - 从包含该行“@ ForTestingOnly“到文件末尾
s/ .../... /g
执行全局(每行)替代
\(... \)
- 捕捉
[{}]
- 替代什么被抓获加上一个换行符
ta
- - 出现在列表bewteen方括号
\1\n
的字符,如果分支标签为“a”
b
- 分支(无标签意味着“结束并再次开始下一行的每行周期) - 该分支作为ta
的”其他“功能,我本可以使用T
代替ta;b;:a
,但sed
一些版本不支持T
:a
- 标签“一”
p
- 打印线(实际上,打印模式缓冲区现在由可能有多个线路用“{ “或‘}’上各一个)
=
- 打印输入文件
第二sed
命令简单地说,删除开始于具有目标串和结束一个行的当前行号在...处由while
循环找到的线。
我顶部的sed
命令说我找到目标字符串并打印它的行号并退出。因为主要的sed
命令正在照顾在正确的地方开始,所以这条线是没有必要的。
内部while
循环查看主sed
命令的输出并增加每个大括号的计数器。当计数匹配时,它停止。
外部的while
循环遍历当前目录中的所有文件。
你应该明确地提一下为什么用“java”标签标记这个问题,我只能怀疑@ForTestingOnly是一个Java注释... – bobah 2010-05-10 16:34:18
小心发布你到目前为止的内容吗? – 2010-05-10 16:34:28
这将是非常容易做到这一点*几乎*正确的,因为你描述它,但要小心诸如评论或字符串文字里面的“}”字符...... – 2010-05-10 16:42:34