簡體   English   中英

grep,sed或awk比較兩個文件的內容

[英]grep, sed or awk to compare content of two files

我正在嘗試用bash解決以下問題。 我有兩個不同的文件(file1,file2),包含如下信息列表:

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

顯示的字符串代表A SINGLE LINE。 意思是如果我這樣做:

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

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

您必須想象數百萬行這樣的行(〜8GB的txt文件)具有不同的ID

我要做的是:

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

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

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

因此,丟棄以4 * 0 0 * * 0 0表示的內容(根據長度固定,但內容不固定。這意味着可能是3 * 1 0 * * 0 1,依此類推。)。

因此,我的file1代表我要查找並保存在file2中的ID的一種“引用”。

我很難解釋。 希望您了解我想做的事。

我認為grep應該可以工作,但是我不知道如何grep僅一行中的一些信息並與另一個文件進行比較。

使file2包含只是想要的密鑰ID的列表:

awk 'NR==FNR{ids[$0];next} $1 in ids{print $1,$10,$11}' file2 file1

可以使用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############

尚不清楚您想要file2的哪個字段,但是一個很好的起點是這樣的:

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

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

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

附帶說明,您可能應該將此數據保留在數據庫中,而不是文本文件中。

4 * 0 0 * * 0 0始終采用相同格式? 在不知道各種可能情況的情況下,很難說出如何回答這個問題。 那么id總是相同的格式嗎?

要使用grep(而不是整行)僅獲取ID,請使用-o 那只會返回匹配的文本,而不是整行。

要寫入新文件並丟棄4 * 0 0 * * 0 0 ,可以使用grep -v grep字符串的逆數。 因此,如果您已經知道要使用的行,請使用grep -v '4 * 0 0 * * 0 0'

無論如何,很多情況將取決於您輸入的確切格式以及各種邊緣情況,但這可能會讓您入門。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM