फाइल करने के लिए grep और लेखन को गति दें

Aug 18 2020

मैं किसी की मदद की सराहना करूंगा। वर्तमान में, मेरे पास 2 फ़ाइलें हैं (दोनों एक ही स्वरूपित हैं) और उन दोनों में प्रत्येक में 2 मिलियन से अधिक लाइनें हैं। नीचे दी गई फाइलों का उदाहरण:

फ़ाइल 1:

00000001 YYYY
00000002 NYNN
00000003 YNYN
...
...

फ़ाइल 2:

00000001 YYNY
00000002 NYNN
00000003 YNYN
...
...

तो ध्यान दें कि प्रत्येक फ़ाइल में पहली पंक्ति अलग है इसलिए मैं फ़ाइल 3 पर प्रिंट करूँगा:

00000001 YYYY

उपरोक्त प्रक्रिया करने के लिए, मेरे पास एक bash स्क्रिप्ट है:

  1. फ़ाइल 2 के लिए पहला आठ अक्षर grep।
  2. मैं फ़ाइल 1 में लाइन के साथ grep के इको / आउटपुट की तुलना करता हूं।
  3. यदि वे अलग-अलग हैं, तो लाइन (फाइल 1 से) फाइल 3 तक लिखें।

मैं नमूना कोड प्रदान करना चाहता था, लेकिन ध्यान रखें, मैंने इसे फ्लाई बीयूटी पर बनाया था, इसकी अवधारणा मेरी स्क्रिप्ट के समान थी। वर्तमान में, मैं 24 घंटे में हूं और केवल 2 मिलियन में से 240k लाइन पर हूं। मैं इसे एक कुशल तरीके से कैसे गति दे सकता हूं?

input="file1"
while IFS= read -r line
do
LineFromFile1=$("${echo $line}") firstEightChars=$("${echo $line:0:8}")
if grep -q "$firstEightChars" file2; then $LineFoundInFile2="$(grep $firstEightCharst file2)"
  if [[ $line == $LineFoundInFile2 ]]; then
    :
  else
    echo $line >> file3 done < "$input"

जवाब

5 dawg Aug 18 2020 at 11:06

यह पायथन लिपि के साथ इतना सरल होगा ।

पाइथन में ज़िप फंक्शन होता है, जिसका उपयोग लाइन द्वारा दो फाइल्स लाइन को पढ़ने और तुलना करने के लिए किया जा सकता है।

उदाहरण बैश स्क्रिप्ट:

echo '00000001 YYYY
00000002 NYNN
00000003 YNYN' >file1


echo '00000001 YYNY
00000002 NYNN
00000003 YNYN' >file2

python3 -c '
with open("file1") as f_1, open("file2") as f_2:
   for t in zip(f_1, f_2):
      if t[0][8:-1] != t[1][8:-1]: print(t[0])'

प्रिंट:

00000001 YYYY

यहां लाभ ( awkउदाहरण के लिए एक साधारण स्क्रिप्ट पर) प्रत्येक फ़ाइल की केवल एक पंक्ति सक्रिय मेमोरी में है - दो लाइनों की तुलना की जा रही है।

हालांकि, यूनिक्स के पास वर्णित समस्या के अन्य समाधान हैं। आप पेस्ट का उपयोग भी कर सकते हैं और awk:

paste file1 file2 | awk '$2!=$4 {print $1 OFS $2}'

या यदि पहले कॉलम में नंबर एक इंडेक्स के रूप में काम कर रहे हैं, तो आप जॉइन और जाग का उपयोग कर सकते हैं :

join file1 file2 | awk '$2!=$3 {print $1 OFS $2}'

या कॉम कमांड (कर्नल 1 और कॉल 3 को दबा रहा है) यदि प्रत्येक फाइल में कॉलम 1 को सॉर्ट किया गया है तो यह भी काम करेगा:

comm -1 -3 file1 file2

सभी तीन यूनिक्स / लिनक्स कमांड / पाइप का उत्पादन:

00000001 YYYY