0

我有以下我试图在 bash 中解决的问题。我有两个不同的文件(file1、file2),其中包含如下信息列表:

HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

显示的字符串代表单行。这意味着如果我这样做:

grep "HWI-1KL104:145:C18ANACXX:5:1101:1168:2164" file1

我的输出是上面的字符串。HWI- 1KL104 :145:C18ANACXX:5:1101:1168:2164代表我的线路的ID

你必须想象像这样的数百万行(大约 8GB 的​​ txt 文件)具有不同的 ID

我要做的是:

  1. 搜索 file1 中存在且存在于 file2 中的那些 ID

  2. 将 file2 中的匹配行保存到仅包含 ID + 以下信息的新文件中:

HWI-1KL104:145:C18ANACXX:5:1101:1196:2120 CCCCTTCTCCAGGGGACCANGTATGTTTCTCTTATGGTCCTCCTTGTTTACTAGCTTCTCTGGCAGTGAGATTGTAGGCTGGTAATCCTTTACTCNNTNNN CCCFFFFFHHHHHHJJJJJJ#4CDEEDCDDDDDC######

因此,丢弃由 4 * 0 0 * * 0 0 表示的东西(在长度方面是固定的,但在内容方面不是固定的......意思可能是 3 * 1 0 * * 0 1 等等......)。

所以我的 file1 代表我想要在 file2 中查找并保存的我的 ID 的一种“参考”。

我很难解释。我希望你明白我想做什么。

我认为 agrep应该可以工作,但我不知道如何grep仅在一行中获取一些信息并与另一个文件进行比较。

4

4 回答 4

2

假设 file2 仅包含您想要的键 ID 列表:

awk 'NR==FNR{ids[$0];next} $1 in ids{print $1,$10,$11}' file2 file1
于 2013-01-28T16:10:23.460 回答
1

可以使用 for 循环

    outputfile="/tmp/something"
    file1=3; file2=4; 
    for ids in $(cat $file1|awk '{print $1}'); 
    do
          #echo working on $id**
          grep $ids $file2|awk '{print $3" "$4" "$5}' >> $outputfile
    done

上面是现在扩展的相同脚本并将输出发送到文件,因此您可以执行脚本并让它处理放置输出的位置,而不是将脚本泵入文件。

当然你可以在大文件上运行它,它可能需要一段时间才能开始,可能需要一些时间才能完成,使用这种方法的问题是它有效且易于使用,但可能不如某些建议使用其他复杂的方法。

您可以启用 id 行上的工作以获得更多详细信息

补充说明:

for filesfound in $(pattern=1101; grep $pattern 3*|awk -F":" '{print $1}'); do
 echo "found $filesfound"; 
 grep "newpattern" $filesfound; 
 done;

found 3
found 33

您可以像这样进一步深入研究初始 grep:

 grep $pattern *|awk -F":" '{print "-- FILE: " $1 " --- ENTIRE_STRING: "$0}'
-- FILE: 3 --- ENTIRE_STRING: 3:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
-- FILE: 33 --- ENTIRE_STRING: 33:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

现在返回文件名|所有字符串,然后查找模式并返回模式之后的所有内容 - 您可以通过在行尾添加更多 awk 语句来自定义它

pattern=1101; grep $pattern *|awk -F":" '{print $1"|"$0}'|awk -F"$pattern" '{print $2}'
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
于 2013-01-28T15:01:21.343 回答
0

目前尚不清楚您想要 file2 的哪些字段,但一个好的起点应该是这样的:

grep -Ff file1 file2 | tr -s ' ' | cut -d' ' -f1,9,10

或者如果 file2 是制表符分隔的:

grep -Ff file1 file2 | cut -f1,9,10

附带说明一下,您可能应该将此数据保存在数据库中,而不是文本文件中。

于 2013-01-28T14:22:52.350 回答
0

总是4 * 0 0 * * 0 0相同的格式?在不了解各种可能情况的情况下,很难说如何回答这个问题。id 呢,它总是采用相同的格式吗?

要使用 grep(而不是整行)获取 id,请使用-o. 这仅返回匹配的文本,而不是整行。

要写入新文件并丢弃4 * 0 0 * * 0 0您可以使用grep -vgrep 字符串的倒数。所以如果你已经知道你正在使用哪条线路,grep -v '4 * 0 0 * * 0 0'

无论如何,这在很大程度上取决于您输入的确切格式以及各种边缘情况,但这可能会让您入门。

于 2013-01-28T14:23:54.187 回答