2016-11-16 71 views
-3

我已经花了最近的2-3天搜索和搜索解决方案,但我似乎无法找到任何。找到图案后找回最后一个和下一个图案

基本上,我有一个包含数十万条记录的文本文件。以下是该文件中包含的模式。

  • 线01:^ d 23554
  • 02行:Q 123 325
  • 03行:Y qwe325
  • 线04:^ P fiwkkwlds
  • 线05:Y qrwe
  • 线06:Y rtewt
  • 07行:^ A 284274 DFL 2939955 001
  • 08号线:F 2739
  • 线09:^ d 23556
  • 第10行:^ķ2994
  • 线11:^ A 284274 DFL 2939966 002
  • 第12行:^ķ29942
  • 第13行:^ķ32423
  • 线14:^ A 284274 DFL 2939957 003
  • 线15:F 23425
  • 线16:^ A 284274 DFL 2939958 004
  • 线17:F 92823
  • 线18:和s o ...

基本上,在数据中没有特定的模式,但是每一行的开始 - >^D,Q,Y,^ P,^ A,F,^ k表示一个简单的消息。

我想找创建一个脚本(优选在壳,PERL或C++),将扫描从第一行一个文件,直到最后一行和

1)检索在^ A线的所有值 2)插入一个分隔符 3)检索的最后一个值的^ d线 4)插入一个分隔符 5)取回的F线 6的下一个值)希望,与数据创建另一个文本文件

根据我之前的例子,下面是结果:

  • 第01行:284274 DFL 2939955 001 | 23554 | 2739
  • 02号线:284274 DFL 2939966 002 | 23556 | 23425
  • 线03:284274 DFL 2939957 003 | 23556 | 23425
  • 线04:284274 DFL 2939958 004 | 23556 | 92823

换句话说:从^ A线

值|前面的^ D行|的值来自下一个F行的值。

有人可以帮助我吗?我一直在阅读有关hashmaps和hashtables,但我不太清楚如何使用它们。我已经看到了许多使用grep的解决方案,例如,在您找到一个模式后:^ A,然后在该模式之前/之后打印最后的x行,因为此数据可能超级随机,前面的^ D消息或下一个F消息可能在任何线路上。

该解决方案将有必要读取文件,并始终在内存中保存^ D和F行值,并找到模式^ A时检索它们。

有人可以帮助我了:)

谢谢!!!!

+0

向我们显示您的代码。你试过什么了? – Ibrahim

+0

嗨易卜拉欣。我没有写任何代码,因为我不确定要做什么。我使用grep进行了一些测试,以从^ A,^ D和F行中检索内容 - 在单独的文件中,但没有多少内容。我正在考虑导入SQL数据库中的文件,并试图找到解决方案,但我认为这对我很有帮助。你有什么建议吗?谢谢! –

回答

-1

这一件作品,但我认为应该是大文件缓慢:

IFS=$'\n' 
readarray -t -O1 data< <(grep -h -e "\^D" -e "\^A" -e "^F" a.txt) 
posA=1 
for i in "${data[@]}"; do 
if [[ "$i" = "^A"* ]]; then 
    textA="${data[$posA]}" 
    posD=$posA 
    posF=$posA 
    textD="" 
    textF="" 
    while [ "$posD" -ge 1 ] && [[ "$textD" != "^D"* ]]; do 
    posD=$(($posD - 1)) 
    textD="${data[$posD]}" 
    done 

    while [ "$posF" -le "${#data[@]}" ] && [[ "$textF" != "F"* ]]; do 
    posF=$(($posF + 1)) 
    textF="${data[$posF]}" 
    done 
    textADF="$textA | $textD | $textF" 
    echo "ADF=$textADF" 
fi 
posA=$(($posA + 1)) 
done 
unset IFS 
exit 

整个的实现是基于

grep -h -e "\^D" -e "\^A" -e "^F" a.txt 

,其输出为存储到数组“数据”,然后代码操纵这个数组,并且事实上while循环将停止在第一次匹配。

也许你可以结合上面的grep头部和尾部来避免数组操作。

PS1:同时应用-n切换到grep会提供一个有趣的输出。

PS2:我不能直接使用“^ A^D F”组来对您的文件进行grep操作,以避免使用代码对数组进行操作,但是这可以通过正则表达式来实现。

+0

乔治,你是男人!这个脚本工作正常,说实话很快。我在我的大文本文件上测试过它。非常感谢!你不明白这有多大帮助。真的很感谢你的努力!竖起大拇指! –

0

这里是伪代码:

d_value = f_value = null 
foreach line in input { 
    if line matches ^A { 
    print line | d_value | f_value 
    d_value = f_value = null 
    } 
    else if line matches ^D 
    a_value = <extracted value> 
    else if line matches ^F 
    f_value = <extracted value> 
} 

它假定d和f的值之前一个。您可以添加错误检查以确保值存在。

希望你对此有所帮助。

0

尝试此正则表达式:

(?<=\^A\s)(?<a>\V+)|(?<=\^D\s)(?<b>\V+)|(?<=\F\s)(?<c>\V+) 

它捕获^A值作为组(a)中,^D值作为组(b)和F值作为(c)组。

匹配这些值后,您可以轻松地在此正则表达式上进行构建,以便使用您选择的任何编程语言进行排序。

演示:https://regex101.com/r/2tipn0/1

+0

嗨易卜拉欣。我试图用grep使用这个正则表达式,但我似乎不知道如何使它正常工作。我尝试了grep -n'^ \^A'file.txt,但是它检索以^ A开头的行。我也试过grep -n -C1'^ \^A'file.txt,它给了我模式之前和之后的行。 –