如何grep文件内容并使用grepped内容创建另一个文件?

时间:2014-07-09 17:20:31

标签: unix awk

我希望得到匹配特定文本的文件的grep内容,然后想要将所有与特定文本匹配的记录保存到新文件中,并且还要确保从原始文件中删除匹配的内容。

    296949657|QL|163744584|163744581|20441||
    292465754|RE|W757|3012|301316469|00|
    296950717|RC|7264|00001|013|27082856203|
    292465754|QL|191427266|191427266|16405||
    296950717|RC|7264|AETNAACTIVE|HHRPPO|27082856203|
    299850356|RC|7700|153447|0891185100102-A|W19007007201|
    292465754|RE|W757|3029|301316469|00|
    299850356|RC|7700|153447|0891185100104-A|W19007007201|
    293695591|QL|743559415|743559410|18452||
    297348183|RC|6602|E924|0048|CD101699303|
    297348183|RC|6602|E924|0051|CD101699303|
    108327882|QL|613440276|613440275|17435||

我写了awk,它可以按预期的方式用于小文件但是对于较大的文件没有按预期工作....我确定我错过了一些东西......

awk '{print $0 > ($0~/RC/?"RC_RECORDS":"TEST.DAT")}' TEST.DAT

关于如何解决这个问题的任何想法。

更新1

现在在上面的文件中,我总是想检查第二列的值到| RC |如果匹配,则将该记录移动到RC_RECORDS文件,如果值匹配| RE |然后将其移至RE_RECORDS,如何做到这一点。

案例1:

例如,如果我有记录

108327882|RE|613440276|613440275|RC||

然后它应该转到RE_RECORDS文件。

案例2:

108327882|RC|613440276|613440275|RE||

那么它应该转到RE_RECORDS

案例3:

108327882|QL|613440276|613440275|RC||

然后它不应该转到RE_RECORDS或RC_RECORDS

案例4:

108327882|QL|613440276|613440275|RE||

然后它不应该转到RE_RECORDS或RC_RECORDS

我的预感是

awk '/\|RC\|/ {print > "RC_RECORDS.DAT";next} {print > "NEWTEST.DAT"}' TEST.DAT | awk '$2 == "RC"'
awk '/\|RE\|/ {print > "RE_RECORDS.DAT";next} {print > "FINAL_NEWTEST.DAT"}' NEWTEST.DAT | awk '$2 == "RE"'

但是想检查是否有更好更快的解决方案可供使用。

更新2

enter image description here

更新3 enter image description here

1 个答案:

答案 0 :(得分:3)

我认为这就是你想要的:

选项1

awk -F'|' '
   $2=="RC" {print >"RC_RECORDS.TXT";next}
   $2=="RE" {print >"RE_RECORDS.TXT";next}
   {print >"OTHER_RECORDS.TXT"}' file

如果您愿意,可以将它全部放在一行,如下所示:

awk -F'|' '$2=="RC"{print >"RC_RECORDS.TXT";next} $2=="RE"{print >"RE_RECORDS.TXT";next}{print >"OTHER_RECORDS.TXT"}' file

选项2

或者您可以看到grep如何比较速度/可读性:

grep -E  "^[[:alnum:]]+\|RC\|"  file > RC_RECORDS.TXT &
grep -E  "^[[:alnum:]]+\|RE\|"  file > RE_RECORDS.TXT &
grep -vE "^[[:alnum:]]+\|R[CE]" file > OTHER_RECORDS.TXT &
wait

选项3

此解决方案使用2 awk个进程,可能会在I / O中实现更好的并行性。第一个awkRC记录提取到文件中,然后将其余记录传递给文件。第二个awkRE记录提取到文件中,并将其余记录传递给OTHER_RECORDS.TXT文件。

awk -F'|' '$2=="RC"{print >"RC_RECORDS.TXT";next} 1' file | awk -F'|' '$2=="RE"{print >"RE_RECORDS.TXT";next} 1' > OTHER_RECORDS.TXT

我创建了一个88M记录文件(3 GB),并在桌面iMac上运行了一些测试,如下所示:

Option 1: 65 seconds
Option 2: 92 seconds
Option 3: 53 seconds

您的里程可能会有所不同。

我的文件看起来像这样,即33%的RE记录,33%的RC记录和其他垃圾:

00000000|RE|abcdef|ghijkl|mnopq|rstu
00000001|RC|abcdef|ghijkl|mnopq|rstu
00000002|XX|abcdef|ghijkl|mnopq|rstu
00000003|RE|abcdef|ghijkl|mnopq|rstu
00000004|RC|abcdef|ghijkl|mnopq|rstu
00000005|XX|abcdef|ghijkl|mnopq|rstu
00000006|RE|abcdef|ghijkl|mnopq|rstu
00000007|RC|abcdef|ghijkl|mnopq|rstu
00000008|XX|abcdef|ghijkl|mnopq|rstu
00000009|RE|abcdef|ghijkl|mnopq|rstu

完整性检查

wc -l *TXT
29333333 OTHER_RECORDS.TXT
29333333 RC_RECORDS.TXT
29333334 RE_RECORDS.TXT
88000000 total