如何从txt文件的一行中获取第一个单词作为上一行的col1数据

时间:2019-05-18 00:37:42

标签: php awk cygwin

我需要在第1列中找到日期(dd.mm.yy)(如awk $ 1?)或作为txt文件中一行的第一个单词(格式始终为dd.mm.yy)用作col上一行中的1,以及所有下一行直到在col 1中的一行中找到新日期为止,然后应将新日期放在上一行中的col 1中,并将所有下一行放在col中,直到找到新日期为止一行1。

Windows 10 Pro,Cygwin,PHP 7.x

我现在归档(PHP)该文件,然后使用PREG_SPLIT_OFFSET_CAPTURE获取每行preg_split(PHP)当前行以获取单词和位置的数组,以获取单词和数组的数据和位置。

preg_split数组中一行的第一个元素始终为[0] =“”(空),位置[1] = 0。如果下一个元素匹配“ preg_match('/ [0-9] {2}。[0-9] {2}。[0-9] {2} /',$ element)”并且其位置至少为X,但不超过Y,这是我想要的日期,它用作上一行中的元素数组中ex的第一个元素,但前一行仅向上,在该日期上找到日期的行,以及所有后续行,直到在一行上找到新日期为止,然后该新日期应用作找到新日期的前一行的日期,而不是之前的日期...

我知道awk可以在比赛之前和之后读取行,但是如何将日期设置为找到日期的行之前行(或其他任何内容)中的数组的第一个元素?

输入:

XXXXXX
  19.05.19
YYYYYYYYYYY
TTTTTTT
UUUUUUUUU
  19.05.19
KKKKKKKKK
GGGGGG

预期输出:
19.05.19 XXXXXXX
19.05.19 YYYYYYYYYYY
TTTTTTT 18.05.19
19.05.19 UUUUUUUUUUUUU
19.05.19 KKKKKKKKKK
19.05.19 GGGGGGG

我在将日期附加到日期之后的后续行上没有问题,但是问题是如何将日期附加到前一行而不是可能存在的日期上。

编辑:

我忘了说我在Windows + Cygwin上。

要读取的源文件在每一行上都有多个前导空格,不知道这是否重要。我手动删除了这些文件进行测试,但是并没有帮助(下面是清除后的原始文件)。并且待读文件的初始样本有所减少,真实文件的行上有多个单词,而我都需要它们(我想这可以通过使用$ 0来完成)。

这是我尝试过的

    #!/bin/bash
    awk '/^([0-9]{2}\.){2}[0-9]{2}/ { date=$1; next }
    NR>1 { print date, prev }
    { prev=$1 }
    END { print date, prev }' Infile.txt

在Infile.txt上

    TTTTT 15MIKROG/ML
    13.11.12            
    90X0.3ML
    D. xxx yyy     
    S. 1 drop 1/d     
    LKE KJJKJJKJK    
    TTTTT 15MIKROG/ML
    22.05.12            
    90X0.3ML
    D. cccc kkkk 
    S. 1 tip 1/d MMMMM LLLLL 
    GGGGG HHHHHH                
    05.10.11   MEDFG 2.5ML          
    D. xxx ooo                   
    S. 1 TIP 1/d MMMMM SSSS 
    GGGGGG HHHHHHH                
    CVCVCVC 20MG/ML+5MG/ML             
    03.03.11
    60X0.2ML                          

在包含日期的行上,如上所述,应该将日期应用于上一行和后续行,直到找到新日期为止。

但是,如果日期在同一行之后有其他内容(空格除外),则此处仅此行

    05.10.11   MEDFG 2.5ML          

然后,该日期不应应用于上一行,而应仅应用于该行和下一行(直到找到新日期为止,它应检查日期是否是该行中唯一的内容,如果是) ,将日期应用于上一行和下一行,等等。

所以评论员给出的结果是预期的结果,但事实是我无法再现结果。

编辑2:

我使用SplFileObject,preg_split完成此操作的PHP方法:

    $splFileObjectFile=new SplFileObject($theFileToProcess);

    foreach($splFileObjectFile as $lineNr=>$lineContent)
        {
        $lineContentArr = preg_split('/ {2,}/', $lineContent, -1, PREG_SPLIT_OFFSET_CAPTURE);
        // To database
        foreach($lineContentArr as $wdKey=>$wordData)
            {
            $wordNr=$wdKey;
            $dataValue=$wordData[0];
            $posValue=$wordData[1];
            $lineNr=$lineNr;
            ...

使用SplFileObject,我得到了行号,并且每隔2个或更多空格使用preg_split,就得到了子数组数组中一行的单词,每个单词本身及其在行中的位置。 / p>

所有这些插入到临时SQLite3数据库中,其中包含行nr,单词nr,单词位置和单词本身的列。

然后有一些SQL获取第一个日期,如果找到日期的行除了日期外什么都没有,还有更多的SQL用该日期更新前一个行日期,等等。

2 个答案:

答案 0 :(得分:1)

这可能是您想要的:

$ awk '
    /^([0-9]{2}\.){2}[0-9]{2}/ { date=$1; next }
    NR>1 { print date, prev }
    { prev=$1 }
    END { print date, prev }
' file
18.05.19 XXXXXX
18.05.19 YYYYYYYYYYY
18.05.19 TTTTTTT
17.05.19 UUUUUUUUU
17.05.19 KKKKKKKKK
17.05.19 GGGGGG

答案 1 :(得分:0)

我认为爱德击败了我,但锻炼得很好。

/^[0-9]{2}.[0-9]{2}.[0-9]{2}$/ {date=$1; next}
{if(last!="") {print date, last} last=$1}
END {print date, last}
awk '
>   /^[0-9]{2}.[0-9]{2}.[0-9]{2}$/ {date=$1; next}
>   {if(last!="") {print date, last} last=$1}
>   END {print date, last}
> ' <<EOF
>                    XXXXXX
> 18.05.19
>                    YYYYYYYYYYY
>                    TTTTTTT
>                    UUUUUUUUU
> 17.05.19
>                    KKKKKKKKK
>                    GGGGGG
> EOF
18.05.19 XXXXXX
18.05.19 YYYYYYYYYYY
18.05.19 TTTTTTT
17.05.19 UUUUUUUUU
17.05.19 KKKKKKKKK
17.05.19 GGGGGG