我有一个文本文件,如下所示:
125
126
127 {
566
567
568
569 # blah blah
570 { #blah blah
700
701 {
数字是左对齐的,模式在增加的意义上总是相同,最后是花括号。我只需要捕获起始数字。大括号总是被找到并限于序列结束。该文件的显示如'125'所示。
总之我需要:
125
566
700
我想出了什么:
grep -A1 '{' | grep -v '{' | grep -oE '(^[0-9]+?)'
但这省略'125',但我通过在头部添加换行并插入{
来克服。
我希望将其减少为单个正则表达式。
欢迎提出建议和更好的算法
答案 0 :(得分:4)
awk 'BEGIN {p=1} p==1 {print $1;p=0} $0~/{/ {p=1}'
Output:
125
566
700
根据上面的文件格式,您可以使用awk和变量/标记来查找开头时{
答案 1 :(得分:3)
sed -n '1p;/{/{
N
s/.*\n\([0-9]\+\).*/\1/p
}' input_file
答案 2 :(得分:2)
您可能需要调整正则表达式,但是:
awk '!k; { k = !/^ *[0-9]* *{/ }'
这将打印第一行以及与正则表达式^ *[0-9]* *{
匹配的行后面的任何行
你可以简化一些事情并做到:
awk '!k;{k=$2!="{"}'
这将打印第一行以及第二行是单个开括号的行后面的任何行。
答案 3 :(得分:1)
我会使用awk和一个标志来捕捉大括号的存在并打印下一行。在开头设置标志,你将获得第一行。
未经测试,但类似:
BEGIN {hasCurly = 1}
{
if(hasCurly)
print $1;
hasCurly = match($2,"^\{");
}
答案 4 :(得分:1)
这是一个纯粹的bash解决方案:
start=1
while read n rest; do
if (( start )); then
printf '%d\n' $n
start=0
elif [[ $rest = \{* ]]; then
start=1
fi
done < input
答案 5 :(得分:1)
sed
将赢得代码高尔夫比赛=):
sed -n '1p;/{/{n;p}' file
删除号码后删除所有内容:
sed -n '1{s/\s*\([0-9]\+\).*/\1/;p};/{/{n;s/\s*\([0-9]\+\).*/\1/;p}' file