शेल स्क्रिप्ट का उपयोग करके स्ट्रिंग से सभी डुप्लिकेट शब्द निकालें


12

मेरे पास एक तार है

"aaa,aaa,aaa,bbb,bbb,ccc,bbb,ccc"

मैं स्ट्रिंग से डुप्लिकेट शब्द को हटाना चाहता हूं फिर आउटपुट जैसा होगा

"aaa,bbb,ccc"

मैंने इस कोड स्रोत की कोशिश की

$ echo "zebra ant spider spider ant zebra ant" | xargs -n1 | sort -u | xargs

यह समान मूल्य के साथ ठीक काम कर रहा है, लेकिन जब मैं अपना चर मूल्य देता हूं तो यह सभी डुप्लिकेट शब्द भी दिखा रहा है।

मैं डुप्लिकेट मान कैसे निकाल सकता / सकती हूं

अपडेट करें

मेरा प्रश्न एक ही स्ट्रिंग में सभी संबंधित मान को जोड़ रहा है यदि उपयोगकर्ता समान है। मेरे पास इस तरह का डेटा है ->

   user name    | colour
    AAA         | red
    AAA         | black
    BBB         | red
    BBB         | blue
    AAA         | blue
    AAA         | red
    CCC         | red
    CCC         | red
    AAA         | green
    AAA         | red
    AAA         | black
    BBB         | red
    BBB         | blue
    AAA         | blue
    AAA         | red
    CCC         | red
    CCC         | red
    AAA         | green

कोडिंग में मैं सभी अलग-अलग उपयोगकर्ता को प्राप्त करता हूं फिर मैं रंगीन स्ट्रिंग को सफलतापूर्वक स्थानांतरित करता हूं। इसके लिए कि मैं कोड का उपयोग कर रहा हूं -

while read the records 

    if [ "$c" == "" ]; then  #$c I defined global
        c="$colour1"
    else
        c="$c,$colour1" 
    fi

जब मैं इस $ c चर को प्रिंट करता हूं तो मुझे आउटपुट मिलता है (उपयोगकर्ता AAA के लिए)

"red,black,blue,red,green,red,black,blue,red,green,"

मैं डुप्लिकेट रंग को हटाना चाहता हूं। फिर वांछित आउटपुट जैसा होना चाहिए

"red,black,blue,green"

इस वांछित आउटपुट के लिए मैंने ऊपर कोड का उपयोग किया

 echo "zebra ant spider spider ant zebra ant" | xargs -n1 | sort -u | xargs

लेकिन यह डुप्लिकेट मान के साथ आउटपुट प्रदर्शित कर रहा है

"लाल, काला, नीला, लाल, हरा, लाल, काला, नीला, लाल, हरा," धन्यवाद


3
कृपया स्पष्ट करें कि आप जो उपयोग कर रहे हैं उसमें क्या गड़बड़ है। मुझे समझ में नहीं आ रहा है कि "जब आप मेरा परिवर्तनीय मूल्य देते हैं" तो आपका क्या मतलब है। आप क्या मूल्य देते हैं? यह कहाँ असफल होता है?
terdon

echo 'aaa aaa aaa bbb bbb ccc bbb ccc' | xargs -n1 | sort -u | xargsदेता है aaa bbb ccc.. तो आपको सटीक कोड दिखाने की ज़रूरत है जो आपको थका हुआ और आउटपुट मिला .. चर में स्ट्रिंग के साथ:s='aaa aaa aaa bbb bbb ccc bbb ccc'; echo "$s" | xargs -n1 | sort -u | xargs
सुंदरदीप

स्ट्रिंग मान गतिशील रूप से आता है। यह समान मूल्य (डुप्लिकेट मान वाले) को प्रिंट कर रहा है।
उर्वशी

1
हाँ, वह कोड दिखाएं जो विफल हो गया, अन्यथा हमें कैसे पता चलेगा कि क्या गलत हुआ है?
सुन्दीप

क्या आदेश मायने रखता है?
जैकब व्लिजम

जवाबों:


12

एक और awk, सिर्फ मनोरंजन के लिए:

$ a="aaa bbb aaa bbb ccc aaa ddd bbb ccc"
$ echo "$a" | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}'
aaa bbb ccc ddd 

वैसे, यहां तक ​​कि आपका समाधान चर के साथ ठीक काम करता है:

$ b="zebra ant spider spider ant zebra ant" 
$ echo "$b" | xargs -n1 | sort -u | xargs
ant spider zebra

नीट दृष्टिकोण। एकमात्र समायोजन जो मुझे करना था वह %sइसके बजाय उपयोग करना था %s%s। इसका कारण यह है कि मैं परिणामों के माध्यम से लूप के लिए कर रहा था और दो सफेद रिक्त स्थान रेगेक्स मैचों के साथ कुछ चुनौतियों का कारण बना।
जेरेमीकैनफील्ड

9

के साथ tr, sortऔरuniq

echo "zebra ant spider spider ant zebra ant" | tr ' ' '\n' | sort | uniq

या

echo "zebra ant spider spider ant zebra ant" | tr ' ' '\n' | sort | uniq | xargs 

एक लाइन पाने के लिए


आपको | xargsआउटपुट को एक पंक्ति में फिर से जोड़ने की आवश्यकता है
फिलिपोस

4
या उपयोग करें sort -u। या यहां तक ​​कि ए awk '!u[$0]++
बेनोइट

2
@ Beno aboutt वाह, मुझे नहीं पता था sort -u। मैं यह sort | uniqसब समय का उपयोग कर रहा हूँ । व्यर्थ कीस्ट्रोक्स ...
गार्डेन


2

गन्नू के साथ sed:

sed ':s;s/\(\<\S*\>\)\(.*\)\<\1\>/\1\2/g;ts'

आप जोड़ने के ;s/ */ /gलिए रिक्त स्थान हटा सकते हैं ।

इस तरह के कार्य: यदि कोई शब्द इस पंक्ति में दूसरी बार है, तो उसे हटा दें और तब तक शुरू करें जब तक कि कोई डाइजेशन नहीं मिलता।


क्या हैं \<और \>?
someonewithpc

@someonewithpc वे किसी भी वर्ण से मेल नहीं खाते हैं, लेकिन एक शब्द की शुरुआत और अंत मेल खाने वाले पदार्थों को रोकने के लिए करते हैं।
फिलिपोस

अच्छा लगा, लेकिन क्या वह पोर्टेबल है? इसके अलावा, व्हॉट्सएप द्वारा अलग किए गए शब्द नहीं हैं? एक शब्द के अंत के बाद व्हाट्सएप से मिलान करने के लिए अनावश्यक लगता है।
someonewithpc

1
@someonewithpc नहीं, यह मानक नहीं है, इसीलिए मैंने gnu sed लिखा है । अच्छी बात यह है कि आपको पहले और आखिरी तार को अलग से संभालना नहीं है
फिलिपोस

2
perl -lane '$,=$";print grep { ! $h{$_}++ } @F'

2

ऑब्जेगेटरी अवेक सॉल्यूशन:

$ echo "ant zebra ant spider spider ant zebra ant" | 
   awk -vRS=" " -vORS=" " '!a[$1] {a[$1]++} END{ for (x in a) print x;  } ' ; echo
zebra ant spider 

( echoन्यूलाइन के लिए फाइनल है)


जाग के लिए एक प्लस! मैं भी मज़े के लिए एक अजीब समाधान बना रहा था। सरणी कुंजियों में इटर्केट्स को रैंडम तरीके से रेकॉर्ड करने के कारण END सेक्शन में यादृच्छिक क्रम में मुद्रित होने की थोड़ी संभावना है।
जॉर्ज वासिलिउ

हां, वे अनिवार्य रूप से यादृच्छिक क्रम में मुद्रित होंगे। sortसमाधान मूल आदेश या तो है, हालांकि नहीं रखता।
ilkachachu

हाँ, अच्छी बात है! यहां तक ​​कि इनपुट की तुलना में अलग-अलग क्रम में प्रिंट।
जॉर्ज वासिलिउ

1
@ilkkachu वास्तव में हमें इनपुट समाप्त होने की प्रतीक्षा करने की आवश्यकता नहीं है। हम आपके कोड में मामूली संशोधन के साथ प्रिंट करने या न करने का निर्णय ले सकते हैं: awk -vRS=" " -vORS=" " '!a[$1]++ {print $1}' ; echoयह आदेश को संरक्षित करता है।

1

अजगर

विकल्प 1

#!/usr/bin/env python
# get_unique_words.py

import sys

l = []
for w in sys.argv[1].split(','):
  if w not in l:
    l += [ w ]
print ','.join(l)

निष्पादन योग्य बनाएं, फिर बैश से कॉल करें:

$ ./get_unique_words.py "aaa,aaa,aaa,bbb,bbb,ccc,bbb,ccc"
aaa,bbb,ccc

या आप इसे बैश फ़ंक्शन के रूप में लागू कर सकते हैं, लेकिन सिंटैक्स गड़बड़ है।

get_unique_words(){
  python -c "
l = []
for w in '$1'.split(','):
  if w not in l:
    l += [ w ]
print ','.join(l)"
}

विकल्प 2

जरूरत पड़ने पर यह विकल्प वन-लाइनर बन सकता है:

#!/usr/bin/env python
# get_unique_words.py

import sys

s_in = sys.argv[1]
l_in = s_in.split(',') # Turn string into a list.
set_out = set(l_in) # Turning a list into a set removes duplicates items.
s_out = ','.join(set_out) 
print s_out

बैश में:

get_unique_words(){
  python -c "print ','.join(set('$1'.split(',')))"
}

0
cat filename | awk '{ delete a; for (i=1; i<=NF; i++) a[$i]++; n=asorti(a, b); for (i=1; i<=n; i++) printf b[i]" "; print "" }' > newfile

मुझे यह नहीं मिलता है
पियरे.वीयरेंस

1
आपके कोड में स्पष्टीकरण की कमी है। बिना किसी स्पष्टीकरण के, जो हो रहा है उसका पालन करना मुश्किल है। आप उस डेटा के बारे में भी धारणा बनाते हैं जो गलत लगता है (व्हाट्सएप-सीमांकित क्षेत्र) और awkउपयोग किए जा रहे विशेष कार्यान्वयन के बारे में ( asorti()यह एक मानक awkकार्य नहीं है )।
Kusalananda

0

फ़ाइल में मूल सारणीबद्ध डेटा का उपयोग करना file:

sed '1d' file | sort -u |
awk '{ color[$1] = ( color[$1] == "" ? $3 : color[$1] "," $3 ) }
     END { for (user in color) print user, color[user] }'

यह उत्पन्न करता है

CCC red
BBB blue,red
AAA black,blue,green,red

पाइपलाइन के तीन चरण:

  1. sedआदेश पहली पंक्ति जो एक हैडर कि हम पढ़ने के लिए नहीं करना चाहती है निकालता है।
  2. sortआदेश हमें अद्वितीय लाइनों देता है। sortजैसे दिखने के बाद नमूना डेटा

    AAA         | black
    AAA         | blue
    AAA         | green
    AAA         | red
    BBB         | blue
    BBB         | red
    CCC         | red
  3. awkआदेश इस डेटा लेता है और सरणी में प्रत्येक उपयोगकर्ता के लिए अल्प विराम द्वारा सीमांकित स्ट्रिंग पैदा करता है color(जहां उपयोगकर्ता नाम सरणी में कुंजी है)। अंत में ( ENDब्लॉक में), सभी एकत्रित डेटा आउटपुट होता है।

-2
a="aaa aaa aaa bbb bbb ccc bbb ccc"
for item in $a
do
   echo $item
done | sort -u | (while read i; do ans="$ans $i"; done ; echo $ans)

कृपया यह बताएं कि आपका कोड कैसे काम करता है और आपने यह और यह क्यों किया।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.