使用sed剪切并粘贴具有完全匹配的线条

时间:2013-09-26 08:47:27

标签: shell unix sed paste cut

我有一个文本文件(~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。 感谢。

3 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

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

这使得来自匹配字符串的sed脚本将匹配的行写入fileB并从fileA中删除它们。

N.B。也是对fileA的备份。

要为每个确切的单词匹配使用不同的文件:

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

答案 1 :(得分:0)

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

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

下一种方法是逐行读取文件,检查行,然后根据检查将其写入Btmp。 (最后还是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)。

答案 2 :(得分: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,因为我们在找到匹配模式时在循环中进行greping。