解析数据的多个实例

时间:2019-06-24 14:45:48

标签: bash parsing text grep sh

我正在尝试从文本文件解析数据的多个实例。我可以grep并抓取一行以及与该发现关联的经/纬度,但是我已经发出了解析多个实例的信息:

require 'open-uri'
require 'nokogiri'
require 'httparty'
require 'byebug'
require 'csv'

class Wheyscrapper
    def whey_scrapper
        company = 'Body+%26+fit'
        url = "https://www.bodyenfitshop.nl/afslanken/afslank-toppers/?manufacturer=#{company}"
        unparsed_page = open(url).read
        parsed_page = Nokogiri::HTML(unparsed_page)
        product_scrapper
        prices_scrapper
        # csv = CSV.open('wheyprotein.csv', 'wb')       
    end 


    def product_scrapper
        products = Array.new
        product_names = parsed_page.css('div.product-primary')
        product_names.each do |product_name| 
            product = {
                name: product_name.css('h2.product-name').text
            }
            products << product 
        end
    end

    def prices_scrapper
        prices = Array.new
        product_prices = parsed_page.css('div.price-box')
        product_prices.each do |product_price|
            price = {
                amount: product_price.css('span.price').text
            }
            prices << price
        end
    end
    byebug
    whey_scrapper
end     

发件人:https://www.spc.noaa.gov/products/outlook/archive/2019/KWNSPTSDY1_201906241300.txt

这是我的代码和结果:

... CATEGORICAL ...

SLGT   33618675 34608681 35658642 36668567 38218542 41018363
       41588227 41918045 41377903 40177805 38927813 37817869
       36678030 35068154 33368262 33078321 32888462 33618675
SLGT   30440169 31710202 33010185 33730148 34010037 33999962
       33709892 32869871 30979883 29539912 29430025 30440169
SLGT   41788755 41698893 42069059 42639132 43889124 44438960
       44438757 43988717 43278708 42398720 41788755
MRGL   42897922 41907743 40147624 38837627 37637700 35897915
       35028021 34038079 33118130 31998226 31698419 32078601
       32818733 33848809 34758764 36998623 38588677 39458701
       40178757 40608870 41069099 43549479 44499512 44809478
       45259379 44989263 45109100 45718986 46478920 46758853
       46738752 46398664 44768565 44308457 43198218
MRGL   29720174 31900221 33650181 34160154 34430032 34649931
       34159800 32539784 31359767 29739808 29299723 28969581
       28959440 99999999 26769674 26579796 26139874
TSTM   45077438 43177245 40597113 99999999 30488085 30248563
       29588926 28739072 28569092 99999999 27138160 27578139
       27908100 27848061 27518032 26968006 26338005 25698017
       25338025 25088048 25058071 25238109 25578128 25888157
       26218171 26578170 26988163 27138160 99999999 29200399
       31910374 33520340 35190229 35450147 36109944 36399709
       35779395 36399167 38559059 40189373 41729594 43029985
       42820283 42860489 43580863 44121062 44521135 45281179
       46271166 47561286 48251548 48671765 49051814 99999999
       38810245 37660271 37120322 36950398 37090559 37380662
       38090741 39410791 39980777 40930695 41380598 41370510
       41190353 40840299 40220263 38810245

结果:

一个MRGL实例以及与该多边形关联的纬度/经度

#!/bin/sh

sed -n '/^MRGL/,/^TSTM/p;/^TSTM/q' day1_status | sed '$ d' | sed -e 's/MRGL//g' > MRGL
while read line
do
  count=1
  ncols=$(echo $line | wc -w)
  while [ $count -le $ncols ]
  do
    echo $line | cut -d' ' -f$count
    ((count++))
  done
done < MRGL > MRGL_output.txt


cat  MRGL_output.txt | sed ':a;s/\B[0-9]\{2\}\>/.&/;ta'| sed 's/./, -/6' > MRGL_final

将上面的行变成单个行实例

more MRGL
   32947889 34137855 35307825 36147735 36327622 35797468
   27107968 25518232 99999999 27088303 28418215 30208125
       30618064

我需要的最终格式

more MRGL_output.txt
32947889
34137855
35307825
36147735
36327622
35797468
27107968
25518232
99999999
27088303
28418215
30208125
30618064

只需解析出现的多个实例即可。

更新以获取更好的解释。

more MRGL_final
32.94, -78.89
34.13, -78.55
35.30, -78.25
36.14, -77.35
36.32, -76.22
35.79, -74.68
27.10, -79.68
25.51, -82.32
99.99, -99.99
27.08, -83.03
28.41, -82.15
30.20, -81.25
30.61, -80.64

想获取上面的数据集,并抓住每种可用的风险ENH,SLGT,MRGL,TSTM纬度和长期,并以这种格式放置:

... CATEGORICAL ...

ENH    38298326 40108202 40518094 40357974 39907953 39017948
       38038052 36148202 35848297 35888367 36618371 38298326
SLGT   30440169 31710202 33010185 33730148 34010037 33999962
       33709892 32869871 30979883 29539912 29430025 30440169
SLGT   33548672 34408661 35918543 36858496 38648520 41018363
       41588227 41918045 41377903 40177805 38927813 37817869
       36678030 35068154 33368262 33078321 32888462 33548672
SLGT   41788755 41698893 42069059 42639132 43889124 44438960
       44438757 43988717 43278708 42398720 41788755
MRGL   29720174 31900221 33650181 34160154 34430032 34649931
       34159800 32539784 31359767 30059748 29299723 28969581
       28959440 99999999 26769674 26579796 26139874
MRGL   42897922 41907743 40147624 38837627 37637700 35897915
       35028021 34038079 33118130 31938225 30758424 30678620
       30988709 34128741 36208583 37738554 39508601 40628878
       41069099 43549479 44499512 44809478 45259379 44989263
       45109100 45718986 46478920 46758853 46738752 46398664
       44768565 44308457 43198218
TSTM   30488085 29978211 29408316 29068379 99999999 27138160
       27578139 27908100 27848061 27518032 26968006 26338005
       25698017 25338025 25088048 25058071 25238109 25578128
       25888157 26218171 26578170 26988163 27138160 99999999
       45427410 43217292 40247181 99999999 28650405 31910374
       33520340 35190229 35450147 36109944 36399709 35779395
       36769245 38319148 40189373 41219571 41299753 39959979
       38220054 37320091 36560136 36070290 36100295 35840394
       36790544 37150626 37880709 39110774 40120876 41150895
       41600769 41890540 43070599 43580863 43390914 43401262
       44171458 45521497 46131301 47181242 47561286 48251548
       48671765 49371856

3 个答案:

答案 0 :(得分:1)

虽然我不确定某些细节,但是这里有一个看起来有点奏效的awk程序。特别是,我不知道经度的最小值是多少。显然,在否定经度之前,小于最小值的值将添加100。因此,您必须将LON_THRESHOLD更改为您认为正确的值。

我试图避免将a​​wk高尔夫计划的惯例吸引到文字上的最低限度,以期希望该计划的运作方式不再那么晦涩。但是无论如何,有些恐慌完全有可能悄悄溜走。最后,我添加了一些解释。

BEGIN      { risk["HIGH"] = "High Risk"
             risk["ENH"] = "Enhanced Risk"
             risk["SLGT"] = "Slight Risk"
             risk["MRGL"] = "Marginal Risk"
             LON_THRESHOLD = 30
             END_STRING = "End:"
           }
END        { if (in_risk) print END_STRING }
in_risk && substr($0, 1, 1) != " " {
             print END_STRING "\n" "\n"
             in_risk = 0
           }
$1 in risk { printf("\"%s\"\n", risk[$1])
             in_risk = 2
           }
in_risk    { for (i = in_risk; i <= NF; ++i) {
               lat = substr($i, 1, 4) / 100
               lon = substr($i, 5, 4) / 100
               if (lon < LON_THRESHOLD) lon += 100
               printf "%5.2f, %.2f\n", lat, -lon
             }
             in_risk = 1
           }

将该程序另存为noaa.awk,然后应用:

awk -f noaa.awk input.txt

通过解释方式:

Awk程序由一系列规则组成。每个规则都有一个谓词(即一个计算结果为真或假值的表达式)和一个动作。

Awk依次处理其输入中的每一行,遍历所有规则并执行其谓词评估为真值的那些行的动作。在操作内部,可以使用$运算符来访问输入中的各个字段(默认情况下,字段用空格分隔)。 $0是整个输入行,$n是字段编号n。与bash / sh不同,$是运算符,可以应用于表达式。

BEGINEND规则是特殊的,因为它们不是实数变量。 BEGIN条规则在执行任何其他处理之前仅执行一次; END规则在所有处理完成后仅执行一次。在此示例中,通常,BEGIN用于初始化参考数据,而END用于进行任何必要的终止-在这种情况下,打印最后的End:行。

在这种情况下,所需的操作实际上取决于我们在文件中的位置,因此有必要构建某种状态机,而我使用变量in_risk进行了设置,该变量有三种可能值:

  • 0或未定义:我们目前不在与风险选择器相对应的区块中。
  • 1:当前行(如果以空格开头)是先前确定的风险选择器的一部分。
  • 2:已检测到当前行以风险选择器开头。

最后两个值之间存在差异的原因是,以风险选择器开头的行中的$1是风险选择器,而以空格开头的行中的$1是实际上是第一个数字。因此,当我们迭代一行中的数字时,对于以风险选择器开头的行,我们必须从$2开始。

答案 1 :(得分:0)

如果您只是问如何将文件AABBCCDD转换为AA.BB, -CC.DD这样的文件:

perl -nE '/^(..)(..)(..)(..)$/ && say "$1.$2, -$3.$4"' MRGL_output.txt

(从您的原始输入到这些行几乎可以肯定有更好的方法,但是我不清楚您发布的代码在做什么或为什么这样做)


认为这样可以正确处理您的原始输入,但是不能确定,因为示例输出中的数字与示例输入不匹配,因此我无法验证:< / p>

perl -anE 'if (/^MRGL/ .. /^TSTM/) { exit if /^TSTM/; push @nums, @F }
           END { for (@nums) {
                   if (/^(..)(..)(..)(..)$/) { say "$1.$2, -$3.$4" }
               }}' day1_status

答案 2 :(得分:0)

有GNU Awk吗?

awk -v RS='\\s+' '
        /[A-Z]/ {p = /^MRGL$/? 1: 0; next}
        p {print gensub(/(..)(..)(..)(..)/, "\\1.\\2, -\\3.\\4", "G")}
' file
  • -v RS'\\s+'-使用任意数量的空格作为记录分隔符
  • /[A-Z]/ {...}-对于具有大写字母的记录,请执行
  • p = /^MRGL$/? 1: 0; next-如果记录是MRGL,则设置标志,否则未设置,但始终跳过任何其他规则。
  • p {print gensub(...)}-如果设置了标志,则打印gensub的结果
  • /(...)/, "\\1", "G"-Capturing groups,后向引用,G小叶替换。