0

我有一个文本文件(~8 GB)。让我们将此文件称为 A。文件 A 大约有 100,000 行,其中 19 个单词和整数由空格分隔。我需要从文件 A 中剪切几行并将它们粘贴到一个新文件(文件 B)中。应从文件 A 中删除这些行。从文件 A 中删除的行应具有完全匹配的字符串。然后我需要重复几次,每次从文件 A 中删除具有不同匹配字符串的行。每次,文件 A 都在变小。我可以使用“sed”但使用两个命令来做到这一点,如下所示:

# Finding lines in file A with matching string and copying those lines to file B
sed -ne '/\<matchingString\>/ p' file A > file B

#Again finding the lines in file A with matching string and deleting those lines,
#writing a tmp file to hold the lines that were not deleted.
sed '/\<matchingString\>/d'file A > tmp

# Replacing file A with the tmp file.
mv tmp file A

这是文件 A 和 B 的示例。我想提取包含 hg15 文件 A 的所有行:

ID pos frac xp mf ...
23 43210 0.1 2 hg15...
...
...

File B:
23 43210 0.1 2 hg15...

我对编写 shell 脚本和使用所有 Unix 工具还很陌生,但我觉得我应该能够更优雅、更快地做到这一点。谁能指导我改进这个脚本。我不需要特别使用“sed”。我一直在搜索 web 和 stackoverflow,但没有找到解决这个确切问题的方法。我正在使用 RedHat 和 bash。谢谢。

4

3 回答 3

1

这可能对您有用(GNU sed):

sed 's|.*|/\\<&\\>/{w fileB\nd}|' matchingString_file | sed -i.bak -f - fileA

这会从匹配的字符串中创建一个 sed 脚本,该脚本将匹配的行写入 fileB 并从 fileA 中删除它们。

注意文件A的备份也被制作了。

要为每个完全匹配的单词创建一个不同的文件,请使用:

sed 's|.*|/\\<&\\>/{w "&.txt"\nd}|' matchingString_file | sed -i.bak -f - fileA
于 2013-09-26T10:02:06.267 回答
0

我会使用grep它,但除了这个小的改进之外,这可能是最快的方法了,即使这意味着将正则表达式应用于每行两次:

grep '<matchingString>' A > B
grep -v '<matchingString>' A > tmp
mv tmp A

下一种方法是逐行读取文件,检查该行,然后根据对 toB或 to的检查将其写入tmp。(最后mv tmp A再一次。)但是没有标准的 Unix 工具可以做到这一点(AFAIK),并且在 shell 中这样做可能会大大降低性能:

while IFS='' read line
do
    if expr "$line" : '<matchingString>' >/dev/null
    then
        echo "$line" 1>&3
    else
        echo "$line"
    fi > B 3> tmp
done < A

您可以尝试使用 Python(或类似的脚本语言)执行此操作:

import re
with open('B', 'w') as b:
  with open('tmp', 'w') as tmp:
    with open('A') as a:
      for line in a:
        if re.match(r'<matchingString>', line):
          b.write(line)
        else:
          tmp.write(line)
os.rename('tmp', 'A')

但这有点超出了这里的范围(不再是 shell)。

于 2013-09-26T09:16:16.077 回答
0

希望对你有帮助...

cat File A | while read line     
do        

    #Finding lines in file A wit matching string and copying those lines to file B
    sed -ne '/\<matchingString\>/ p' file A >> file B

    #Again finding the lines in file A with matching string and deleting those lines  
    #writing a tmp file to hold the lines that were not deleted     
    sed '/\<matchingString\>/d'file A >> tmp

done

#once you are done with greping and copy pasting Replacing file A with the tmp file    
`mv tmp file A`

PS:我正在附加到文件 B 因为我们在找到匹配模式时正在循环中查找。

于 2013-09-26T09:22:53.640 回答