2014-10-30 45 views
0

我有一個包含版本名稱和版本號的文件。第一個文件的內容看起來原樣檢查unix中是否存在另一個文件中的字符串

File1- 

<Line contains the name of product1> 
package_name0_9_8 >= 1.2.3x-4.5.6 
package_name0_9_8-32bit >= 3.6.1g-3.5.1 
package_name0_9_8-xx >= 6.3.2v-3.0.4 
<Line contains the name of product2> 
anotherpackage_name0_9_8 >= 3.5.6u-3.6.5 

而且,

File2.xml- 

<package name="package_name0_9_8" version="1.2.3x-4.4.4"/> 
<package name="package_name0_9_8-32bit" version="3.6.1g-3.4.0"/> 
. 
. 

有沒有一種方法來檢查程序包是否存在等存在於文件1與文件2的程序包,並檢查相應的File1中package_name的版本與File2的package_name的相應版本的版本?

我很坦率地說,在連接'grep'和'awk'命令以及在此使用的選項時,我非常弱。請幫忙。

+0

您有興趣在Python解決方案中,偶然? – Shule 2014-10-30 05:52:48

+1

@ user2962794:是的,非常歡迎。 Python解決方案將會很好。 – Goblin 2014-10-30 06:10:47

+0

@shellter:謝謝。是的,這條線沒有意義。我想,我會以這種方式輸出。 – Goblin 2014-10-30 06:12:31

回答

0

for a in $(sed -n '/>=/p' File1.txt | grep -o '^[^ ]*'); do for b in $(sed -n "/^$a /{s/.*>=\(.*\)$/\1/p}" File1.txt); do ((! $(grep -c "$a.*$b" File2.txt))) && (echo "$a $b" >> missing_pkgs.txt); done; done;

這是一個快速班輪 - 你可以把它打印出來有點漂亮

這個作品被嵌套的循環,抓住兩件分成變量的方法(你可以做到這一點與讀並且如果你願意的話把它們放在一個循環中),然後用grep對第二個文件中的出現次數進行計數,並且每當計數爲零時,它將使得測試(())變爲真的值並回顯丟失的包到文件missing_pkgs。TXT

這裏是另一個快速的一個襯墊,做同樣的事情,除了有一個循環和變量更高效的加載通過閱讀

while read each; do read a b < <(echo $each) && ((! $(grep -c "$a.*$b" File2.txt))) && (echo "$a $b" >> missing_pkgs.txt); done < <(awk '/>=/{ print $1" "$3 }' File1.txt)

更簡單:

while read a b; do ((! $(grep -c "$a.*$b" File2.txt))) && (echo "$a $b" >> missing_pkgs.txt); done < <(awk '/>=/{ print $1" "$3 }' File1.txt)

+0

謝謝!使用你的想法,我試着用'sed -n「/> =/p」File1 |「 grep -o「^ [^] *」> package_names'和'sed -n「/^/{s/.*>= \(。* \)/ \\ 1/p}」File1> package_versions'。我只是把這些行放到shell腳本中(只是爲了使它更簡單和明顯)並運行腳本。現在,相同的shell腳本應該檢查'File2'中'package1s'的'line1',然後'File2'檢查'package_versions'的'line1'。請幫忙。我在shell腳本中的想法也少得多。 – Goblin 2014-11-04 08:45:22

+0

如果想要進一步減少它,可以使用更簡單的第二個版本:while read a b; ((!$(grep -c「$ a。* $ b」File2.txt)))&&(echo「$ a $ b」>> missing_pkgs.txt);完成< <(awk '/> =/{print $ 1「」$ 3}'File1.txt) – 2014-11-04 09:14:58

+0

明白了。而且,如何將'$ 1'和'$ 3'存儲到最後一部分'<(awk '/> =/{print $ 1「」$ 3}'File1.txt)'中使用的兩個單獨變量中,以便稍後可以使用它們更好的輸出格式部分? – Goblin 2014-11-05 08:24:03

0
sed -n 's².*²s#<package name="\\(&"/>#\\1 Present#p²;s/ *>= */\\)" *version="/p' File1 > /tmp/File1.sed 
sed -n -f /tmp/File1.sed File2 
rm /tmp/File1.sed 
  • 沒有像AWK能做的指令,但做的工作(POSIX版本,所以--posix在GNU sed的
  • 你可以改變那是\\1 Present文本,其中\\1將是輸出消息軟件包名稱(只需要修改,版本也可以使用)
+1

或者你可以發送第一個命令的輸出到第二個:'sed -n'stuff'File1 | sed -n -f - File2' – aragaer 2014-10-30 09:20:00

+1

@NeronLeVelu:我可以知道方形符號在第一行中的作用嗎?我不熟悉那個標誌。另外,你能否詳細說明第二個要點? – Goblin 2014-10-30 09:39:32

+0

''''''''''在這裏被用作傳統的'/ /'模式分隔符而不是在模式本身中使用的'/'。 sed以's'之後的拳頭字符作爲分隔符。因爲它在2個不同的sed中使用(第一個創建第二個)我使用2個不同的分隔符。 – NeronLeVelu 2014-10-30 09:45:52

0

看起來你已經有了一個更接近你想要的格式的短得多的解決方案但是,因爲我問是否Python解決方案可以工作,你說的沒錯,看看這裏的代碼:

http://pastebin.com/F5LYrmea

(我還沒有調試多一點更,但它似乎工作至少比你的示例文件多一點。我將代碼發佈到公共領域。據CC的製造商稱,CC-BY-SA不是軟件許可證;所以,這就是爲什麼我沒有在這裏發佈它,因爲張貼在這裏會給它許可證。另外,您可以在提供的鏈接中獲得特定於Python的語法突出顯示。)

基本上,這是很多複雜的文本解析。沒有太多的解釋算法。它獲取這兩個文件的內容,去掉包,它們的版本和操作數(將所有這些文件放在字典中供以後使用),並循環遍歷另一個文件的行並比較版本;那麼它會告訴你哪些匹配,哪些不匹配。

相關問題