我需要在第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用该日期更新前一个行日期,等等。
答案 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