पहले तीन कॉलम को प्रिंट करें


112

बहुत बोझिल:

awk '{print " "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13}' things

43
क्या कोई कारण है जो आप अभी उपयोग नहीं कर सकते हैं cut -f3-?
कास्कैबेल

1
@hhh अच्छा एक .. मुझे एक सारांश उत्तर का विचार पसंद है।
क्रिस सेमोर

2
@ जेफ्रोमी - क्योंकि कट के साथ लाइन बफरिंग मुद्दे हैं, जो
जाग


@ जेफ्रोमी - भी कार्रवाई cutसे पहले regexes नहीं है {}, और फिर यह क्षेत्र delimiters (रिक्त स्थान की चर संख्या) के साथ तरीका है, और आपको उन्हें मैन्युअल रूप से निर्दिष्ट करना होगा। मुझे लगता है कि ओपी कुछ shift Nकमांड के बारे में सुनना चाहता था , जो मौजूद नहीं है। निकटतम है $1="";$2="";(...);print}, लेकिन मेरे मामले में यह कुछ अग्रणी स्थान (शायद विभाजक) छोड़ देता है।
टॉमस गैंडर

जवाबों:


50

एक समाधान जो अतिरिक्त प्रमुख या अनुगामी व्हाट्सएप को नहीं जोड़ता है :

awk '{ for(i=4; i<NF; i++) printf "%s",$i OFS; if(NF) printf "%s",$NF; printf ORS}'

### Example ###
$ echo '1 2 3 4 5 6 7' |
  awk '{for(i=4;i<NF;i++)printf"%s",$i OFS;if(NF)printf"%s",$NF;printf ORS}' |
  tr ' ' '-'
4-5-6-7

Sudo_O टर्नरी ऑपरेटर का उपयोग करके एक सुंदर सुधार का प्रस्ताव करता हैNF?ORS:OFS

$ echo '1 2 3 4 5 6 7' |
  awk '{ for(i=4; i<=NF; i++) printf "%s",$i (i==NF?ORS:OFS) }' |
  tr ' ' '-'
4-5-6-7

EdMorton खेतों के बीच मूल व्हाट्सएप को संरक्षित करने वाला एक समाधान देता है:

$ echo '1   2 3 4   5    6 7' |
  awk '{ sub(/([^ ]+ +){3}/,"") }1' |
  tr ' ' '-'
4---5----6-7

बाइनरीज़ेब्रा दो भयानक समाधान भी प्रदान करता है:
(ये समाधान मूल स्ट्रिंग से अनुगामी रिक्त स्थान को भी संरक्षित करते हैं)

$ echo -e ' 1   2\t \t3     4   5   6 7 \t 8\t ' |
  awk -v n=3 '{ for ( i=1; i<=n; i++) { sub("^["FS"]*[^"FS"]+["FS"]+","",$0);} } 1 ' |
  sed 's/ /./g;s/\t/->/g;s/^/"/;s/$/"/'
"4...5...6.7.->.8->."

$ echo -e ' 1   2\t \t3     4   5   6 7 \t 8\t ' |
  awk -v n=3 '{ print gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1); }' |
  sed 's/ /./g;s/\t/->/g;s/^/"/;s/$/"/'
"4...5...6.7.->.8->."

टिप्पणियों में लार्सर द्वारा दिया गया समाधान लगभग सही है:

$ echo '1 2 3 4 5 6 7' | 
  awk '{for (i=3;i<=NF;i++) $(i-2)=$i; NF=NF-2; print $0}' | tr  ' ' '-'
3-4-5-6-7

यह लार्स सॉल्यूशन का निश्चित और पैरामीरिज्ड संस्करण है :

$ echo '1 2 3 4 5 6 7' | 
  awk '{for(i=n;i<=NF;i++)$(i-(n-1))=$i;NF=NF-(n-1);print $0}' n=4 | tr ' ' '-'
4-5-6-7

सितंबर -2016 से पहले अन्य सभी उत्तर अच्छे हैं लेकिन अतिरिक्त स्थान जोड़ें:


एडमॉर्टन का जवाब मेरे लिए काम नहीं आया (4.1.2 (1) -release, GNU Awk 3.1.7 या bash 3.2.25 (1) -release, GNU Awk 3.1.5) के लिए काम नहीं किया, लेकिन यहां एक और तरीका मिला :echo ' This is a test' | awk '{print substr($0, index($0,$3))}'
echch

1
@elysch नहीं, यह सामान्य रूप से काम नहीं करेगा, यह सिर्फ कुछ विशिष्ट इनपुट मूल्यों को देखते हुए काम करता है। आपके जवाब के नीचे मैंने जो टिप्पणी की है, उसे देखें।
एड मॉर्टन

1
हाय @fedorqui। मेरा जवाब पहले वाला है। अपने मूल उत्तर में मैं समझा रहा था कि अन्य उत्तर सही क्यों नहीं थे (अतिरिक्त अग्रणी या अनुगामी व्हाट्सएप)। कुछ लोगों ने टिप्पणियों के भीतर वृद्धि का प्रस्ताव दिया है। हमने ओपी को अधिक सही उत्तर चुनने के लिए कहा है, और उसने मेरा चयन किया है। कुछ अन्य योगदानकर्ताओं ने मेरे उत्तर को संदर्भ के लिए संपादित किया है (उत्तर देखें)। क्या यह आपके लिए स्पष्ट है? मेरे उत्तर की समझ को बेहतर बनाने के लिए आप मुझे क्या सलाह देंगे? चीयर्स ;-)
ओलिब्रे

1
आप बिल्कुल सही हैं और मुझे अपनी गलतफहमी के लिए बहुत खेद है। मैंने उत्तर को तेजी से पढ़ा और आपके मूल उत्तर पर ध्यान नहीं दिया (हां, मैंने बहुत तेजी से पढ़ा)। +1 के उत्तर के लिए ही अच्छी तरकीब का उपयोग करते हुए NF-1 तक लूप करें और फिर अतिरिक्त व्हाट्सएप से बचने के लिए अंतिम तत्व को प्रिंट करें। और फिर से क्षमा करें! (भविष्य के पाठकों से गलतफहमी को रोकने के लिए एक-एक दिन में अपनी टिप्पणी हटा दूंगा)।
फेडोरक्वी 'एसओ

1
मैं किसी प्रकार के शीर्ष लेख का उपयोग करूंगा: <आपका उत्तर> और फिर एक क्षैतिज नियम के बाद एक बड़ा शीर्षक "अन्य उत्तरों की तुलना"। अन्यथा, इस तुलना को दूसरे उत्तर में ले जाएं, क्योंकि स्पष्ट रूप से लोग "
गीम माई

75
awk '{for(i=1;i<4;i++) $i="";print}' file

4
यह अग्रणी होगा OFSक्योंकि आप NFरिकॉर्ड में अग्रणी स्थान के साथ सौदा नहीं करते हैं।
क्रिस सेमोर

70

कट का उपयोग करें

$ cut -f4-13 file

या यदि आप जाग पर जोर देते हैं और $ 13 अंतिम क्षेत्र है

$ awk '{$1=$2=$3="";print}' file

अन्य

$ awk '{for(i=4;i<=13;i++)printf "%s ",$i;printf "\n"}' file

14
शायद पिछले उदाहरण में "13" की तुलना में "एनएफ" का उपयोग करना बेहतर है।
ग्लेन जैकमैन

2
2 परिदृश्य जो तय करने के लिए ओपी तक है। अगर 13 अंतिम क्षेत्र है, तो NF का उपयोग करना ठीक है। यदि नहीं, तो 13 का उपयोग करना उचित है।
ghostdog74

3
2 को $ 0 की शुरुआत से OFS की 3 प्रतियां हटाने की आवश्यकता है। 3 के साथ बेहतर होगा printf "%s ",$i, क्योंकि आप नहीं जानते कि $iइसमें शामिल हो सकता है %sया पसंद नहीं है। लेकिन वह अंत में एक अतिरिक्त स्थान प्रिंट करेगा।
dubiousjim

38

इसे इस्तेमाल करे:

awk '{ $1=""; $2=""; $3=""; print $0 }'

1
यह कितना अच्छा है क्योंकि यह गतिशील है। आप अंत में कॉलम जोड़ सकते हैं और अपनी लिपियों को फिर से नहीं लिख सकते।
मिंसमैन

1
यह उस सटीक समस्या को प्रदर्शित करता है जिससे सवाल आपके साथ निपटने की कोशिश कर रहा है। 100 वें क्षेत्र से प्रिंट के बारे में क्या? उल्लेख करने के लिए ध्यान दें NFजिससे आप अग्रणी नहीं हैं OFS
क्रिस सेमोर

24

ऐसा करने का सही तरीका आरई अंतराल के साथ है क्योंकि यह आपको केवल यह बताता है कि कितने फ़ील्ड को छोड़ना है, और शेष क्षेत्रों के लिए अंतर-क्षेत्र रिक्ति को बनाए रखना है।

शेष 3 क्षेत्रों के बीच अंतर को प्रभावित किए बिना पहले 3 क्षेत्रों को छोड़ देने के लिए उदाहरण के रूप में इनपुट के प्रारूप को देखते हुए हम इस प्रश्न पर चर्चा कर रहे हैं:

$ echo '1   2 3 4   5    6' |
awk '{sub(/([^ ]+ +){3}/,"")}1'
4   5    6

यदि आप प्रमुख स्थानों और गैर-रिक्त स्थानों को समायोजित करना चाहते हैं, लेकिन फिर डिफ़ॉल्ट एफएस के साथ, तो यह है:

$ echo '  1   2 3 4   5    6' |
awk '{sub(/[[:space:]]*([^[:space:]]+[[:space:]]+){3}/,"")}1'
4   5    6

यदि आपके पास एक FS है जो एक आरई है जिसे आप एक चरित्र सेट में नकार नहीं सकते हैं, तो आप इसे पहले एक चार में बदल सकते हैं (आरएस आदर्श है यदि यह एक एकल है क्योंकि एक आरएस CANNOT एक क्षेत्र के भीतर दिखाई देता है, अन्यथा SUBSEP पर विचार करें), फिर आरई अंतराल अंतराल को लागू करें, फिर ओएफएस में परिवर्तित करें। जैसे यदि "।" की जंजीरों को अलग किया जाता है:

$ echo '1...2.3.4...5....6' |
awk -F'[.]+' '{gsub(FS,RS);sub("([^"RS"]+["RS"]+){3}","");gsub(RS,OFS)}1'
4 5 6

जाहिर है अगर OFS एक सिंगल चार है और यह इनपुट क्षेत्रों में दिखाई नहीं दे सकता है तो आप इसे कम कर सकते हैं:

$ echo '1...2.3.4...5....6' |
awk -F'[.]+' '{gsub(FS,OFS); sub("([^"OFS"]+["OFS"]+){3}","")}1'
4 5 6

फिर आपके पास एक ही मुद्दा है कि सभी लूप-आधारित समाधानों के साथ जो खेतों को फिर से सौंपता है - एफएस को ओएफएस में बदल दिया जाता है। यदि यह एक समस्या है, तो आपको GNU awks 'patsplit () फ़ंक्शन को देखने की आवश्यकता है।


मेरे लिए काम नहीं किया (4.1.2 (1) -release, GNU Awk 3.1.7 या bash 3.2.25 (1) -release, GNU Awk 3.1.5) के लिए काम नहीं किया, लेकिन यहाँ एक और तरीका मिला :echo ' This is a test' | awk '{print substr($0, index($0,$3))}'
Elysch

2
नहीं, यदि $ 1 या $ 2 में वह स्ट्रिंग है जिसमें $ 3 सेट है तो वह विफल हो जाएगी। उदाहरण के लिए, कोशिश करें echo ' That is a test' | awk '{print substr($0, index($0,$3))}'और आप पाएंगे कि a$ 3 aअंदर That$ 1 से मेल खाता है । अपने जैसे बहुत पुराने संस्करण में आपको ध्वज के साथ आरई अंतराल को सक्षम करने की आवश्यकता होती है --re-interval
एड मॉर्टन

2
आप सही हैं, ध्यान नहीं दिया। वैसे, वास्तव में आपकी टिप्पणी की सराहना करते हैं। कई बार तत्वों की संख्या निर्दिष्ट करने के लिए "{}" के साथ एक regex का उपयोग करना चाहते थे और कभी भी आदमी में "--re- अंतराल" नहीं देखा था। आपके लिए +1।
ईलिश

1
1एक सही स्थिति है और इसलिए वर्तमान रिकॉर्ड को प्रिंट करने की डिफ़ॉल्ट awk कार्रवाई को आमंत्रित करता है।
एड मॉर्टन

1
idk कितना विहित है, लेकिन मैंने अब एक उत्तर जोड़ा।
एड मॉर्टन

10

बहुत अधिक सभी उत्तर वर्तमान में या तो अग्रणी स्थान, अनुगामी रिक्त स्थान या कुछ अन्य विभाजक मुद्दे जोड़ते हैं। चौथे क्षेत्र से चयन करने के लिए जहां विभाजक व्हाट्सएप है और आउटपुट विभाजक का उपयोग करके एक एकल स्थान awkहोगा:

awk '{for(i=4;i<=NF;i++)printf "%s",$i (i==NF?ORS:OFS)}' file

आरंभ करने के लिए आप जो क्षेत्र कर सकते हैं, वह करें:

awk '{for(i=n;i<=NF;i++)printf "%s",$i (i==NF?ORS:OFS)}' n=4 file

और अंत क्षेत्र भी:

awk '{for(i=n;i<=m=(m>NF?NF:m);i++)printf "%s",$i (i==m?ORS:OFS)}' n=4 m=10 file

6
awk '{$1=$2=$3="";$0=$0;$1=$1}1'

इनपुट

1 2 3 4 5 6 7

उत्पादन

4 5 6 7

4
echo 1 2 3 4 5| awk '{ for (i=3; i<=NF; i++) print $i }'

3
या उन्हें एक ही पंक्ति में लाने के लिए, $ 3 से $ 1, आदि असाइन करें और फिर NF को सही संख्या में फ़ील्ड में बदलें। echo 1 2 3 4 5| awk '{ for (i=3; i<=NF; i++) $(i-2)=$i; NF=NF-2; print $0 }'
लार्सर

हाय @ लारस। आपकी प्रस्तावित कमांड लाइन एक सही उत्तर है। अन्य सभी उत्तर अतिरिक्त स्थान (अग्रणी या अनुगामी) जोड़ते हैं। कृपया अपनी कमांड लाइन एक नए उत्तर के भीतर पोस्ट करें, मैं इसे वोट
करूंगा

1
Hi @sudo_O, मैं @larsr से बात कर रहा था, कमांड लाइन के बारे में जो उन्होंने अपनी टिप्पणी में प्रस्तावित की थी। मैंने क़िप्रोको (गलतफहमी) का पता लगाने से पहले लगभग पांच मिनट बिताए। मैं सहमत हूं, @Vetsin उत्तर ORSफ़ील्ड्स के बीच नई लाइनें ( ) सम्मिलित करता है । आपकी पहल के लिए ब्रावो (मुझे आपका जवाब पसंद है)। चीयर्स
ओलिब्रे

3

प्रिंट स्टेटमेंट का उपयोग करने से बचने का दूसरा तरीका:

 $ awk '{$1=$2=$3=""}sub("^"FS"*","")' file

किसी स्थिति के सत्य होने पर awk में डिफ़ॉल्ट क्रिया होती है।


यह सभी समस्याओं @lhf उत्तर है .. यह सिर्फ छोटा है।
क्रिस सेमोर

बहुत अच्छा विचार;) मेरे जवाब से बेहतर! (मैं पिछले साल आपके उत्तर को पहले ही देख चुका हूं) चीयर्स
ओलिवर

यह होना चाहिए: awk '{$1=$2=$3=""}sub("^"OFS"+","")' fileजैसा कि ओएफएस है जो $ 1, $ 2, और $ 3 सामग्री को बदलने के बाद बचा है।

3

मैं विश्वास नहीं कर सकता कि कोई भी सादे खोल की पेशकश की

while read -r a b c d; do echo "$d"; done < file

इसी तरह के समाधान के लिए +1 ... लेकिन अगर fileबड़ा (> 10-30KiB) है तो इसमें प्रदर्शन के मुद्दे हो सकते हैं । बड़ी फ़ाइलों के लिए awkसमाधान बेहतर प्रदर्शन करता है।
ट्रू य सिप

3

विकल्प 1 से 3 में कई व्हाट्सएप (लेकिन सरल हैं) के मुद्दे हैं। यही कारण है कि विकल्प 4 और 5 को विकसित करना है, जो बिना किसी समस्या के कई सफेद रिक्त स्थान को संसाधित करते हैं। बेशक, यदि विकल्प 4 या 5 का उपयोग किया जाता है, तो n=0दोनों किसी भी प्रमुख व्हाट्सएप को संरक्षित करेंगे, n=0जिसका अर्थ है कोई विभाजन नहीं।

विकल्प 1

एक सरल कटौती समाधान (एकल सीमांकक के साथ काम करता है):

$ echo '1 2 3 4 5 6 7 8' | cut -d' ' -f4-
4 5 6 7 8

विकल्प 2

एक अजीब री-कैल्क को मजबूर करना कभी-कभी समस्या को हल करता है (जोड़ा के कुछ संस्करणों के साथ काम करता है)

$ echo '1 2 3 4 5 6 7 8' | awk '{ $1=$2=$3="";$0=$0;} NF=NF'
4 5 6 7 8

विकल्प 3

प्रत्येक क्षेत्र के साथ तैयार मुद्रण printfअधिक नियंत्रण देगा:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=3 '{ for (i=n+1; i<=NF; i++){printf("%s%s",$i,i==NF?RS:OFS);} }'
4 5 6 7 8

हालाँकि, पिछले सभी उत्तर फ़ील्ड के बीच सभी FS को OFS में बदल देते हैं। चलो उस के समाधान के एक जोड़े का निर्माण।

विकल्प 4

खेतों और सीमांकक को हटाने के लिए उप के साथ एक लूप अधिक पोर्टेबल है, और FS के OFS में परिवर्तन को ट्रिगर नहीं करता है:

$ echo '    1    2  3     4   5   6 7     8  ' |
awk -v n=3 '{ for(i=1;i<=n;i++) { sub("^["FS"]*[^"FS"]+["FS"]+","",$0);} } 1 '
4   5   6 7     8

नोट: "^ [" "FS"] * "अग्रणी रिक्त स्थान के साथ एक इनपुट स्वीकार करना है।

विकल्प 5

एक समाधान का निर्माण करना काफी संभव है जो अतिरिक्त अग्रणी या अनुगामी व्हाट्सएप को नहीं जोड़ता है, और gensubजीएनयू अवेक से फ़ंक्शन का उपयोग करके मौजूदा व्हाट्सएप को संरक्षित करता है:

$ echo '    1    2  3     4   5   6 7     8  ' |
awk -v n=3 '{ print gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1); }'
4   5   6 7     8 

यह भी एक क्षेत्र की सूची स्वैप करने के लिए इस्तेमाल किया जा सकता है एक गिनती दी n:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=3 '{ a=gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1);
                b=gensub("^(.*)("a")","\\1",1);
                print "|"a"|","!"b"!";
               }'
|4   5   6 7     8  | !    1    2  3     !

बेशक, ऐसे मामले में, ओएफएस का उपयोग लाइन के दोनों हिस्सों को अलग करने के लिए किया जाता है, और खेतों के पीछे की सफेद जगह अभी भी मुद्रित होती है।

नोट 1: ["FS"]* इनपुट लाइन में अग्रणी स्थानों की अनुमति देने के लिए उपयोग किया जाता है।


हाय BZ आपका जवाब अच्छा है। लेकिन विकल्प 3 एक अंतरिक्ष (जैसे " 1 2 3 4 5 6 7 8 ") के साथ स्ट्रिंग शुरुआत पर काम नहीं करता है । विकल्प 4 अच्छा है लेकिन एक अंतरिक्ष के साथ स्ट्रिंग शुरुआत का उपयोग करके एक अग्रणी स्थान छोड़ दें। क्या आपको लगता है कि यह ठीक करने योग्य है? आप echo " 1 2 3 4 5 6 7 8 " | your awk script | sed 's/ /./g;s/\t/->/g;s/^/"/;s/$/"/'प्रमुख / मध्य / अनुगामी स्थानों को सत्यापित करने के लिए आदेश का उपयोग कर सकते हैं ... चीयर्स;)
ओलिब्रे

हाय @olibre। विकल्प 3 सफेद स्थान के साथ विफल हो जाता है विकल्प 4 और 5. विकसित करने का कारण है। विकल्प 4 केवल एक प्रमुख स्थान छोड़ता है यदि इनपुट में यह है और n 0 पर सेट है (n = 0)। मेरा मानना ​​है कि खेतों का चयन नहीं होने पर (आईएमओ को ठीक करने के लिए कुछ नहीं) सही उत्तर है। चीयर्स।

ठीक है। अतिरिक्त जानकारी के लिए धन्यवाद :-) कृपया अपने उत्तर को बेहतर बनाने के लिए इन अतिरिक्त जानकारी को प्रदान करें :-) चीयर्स
ओलिब्रे

परफेक्ट :-) आपका उपयोगकर्ता किस दया से विकलांग है :-(
olibre

1

कट में एक --complement फ़्लैग है जो कॉलम को हटाना आसान (और तेज़) बनाता है। परिणामी वाक्यविन्यास आप क्या करना चाहते हैं के साथ अनुरूप है - समाधान को पढ़ने / समझने के लिए आसान बनाना। पूरक उस मामले के लिए भी काम करता है जहां आप गैर-सन्निहित कॉलम हटाना चाहते हैं।

$ foo='1 2 3 %s 5 6 7'
$ echo "$foo" | cut --complement -d' ' -f1-3
%s 5 6 7
$

क्या आप कृपया अपना उत्तर बता सकते हैं?
ज़ुलु

क्या ऊपर दिया गया संपादन समझ में मदद करता है? बिंदु कटौती के पूरक ध्वज का उपयोग करना है। समाधान AWK या पर्ल आधारित समाधानों की तुलना में तेज़ और अधिक संक्षिप्त कार्यान्वयन होना चाहिए। साथ ही, मनमाने कॉलम काटे जा सकते हैं।
माइकल बैक

1

पर्ल समाधान जो प्रमुख या अनुगामी व्हाट्सएप को नहीं जोड़ता है:

perl -lane 'splice @F,0,3; print join " ",@F' file

पर्ल @Fautosplit सरणी सूचकांक पर शुरू होता है 0, जबकि awk क्षेत्रों के साथ शुरू$1


कॉमा-सीमांकित डेटा के लिए पर्ल समाधान:

perl -F, -lane 'splice @F,0,3; print join ",",@F' file

पायथन समाधान:

python -c "import sys;[sys.stdout.write(' '.join(line.split()[3:]) + '\n') for line in sys.stdin]" < file


0

मेरे लिए अनुरोध के लिए सबसे कॉम्पैक्ट और आज्ञाकारी समाधान है

$ a='1   2\t \t3     4   5   6 7 \t 8\t '; 
$ echo -e "$a" | awk -v n=3 '{while (i<n) {i++; sub($1 FS"*", "")}; print $0}'

और अगर आपके पास उदाहरण के लिए फ़ाइल foo.txt के रूप में संसाधित करने के लिए अधिक लाइनें हैं , तो मुझे 0 से रीसेट करना न भूलें:

$ awk -v n=3 '{i=0; while (i<n) {i++; sub($1 FS"*", "")}; print $0}' foo.txt

आपका मंच धन्यवाद।


0

जैसा कि मैं पहले उच्च उत्थान से नाराज़ था, लेकिन गलत जवाब मुझे वहाँ एक उत्तर लिखने के लिए पर्याप्त मिला, और यहाँ गलत उत्तर इस तरह से चिह्नित हैं, यहाँ मेरा बिट है। मुझे प्रस्तावित समाधान पसंद नहीं हैं क्योंकि मैं उत्तर को इतना जटिल बनाने का कोई कारण नहीं देख सकता।

मेरे पास एक लॉग है जहां $ 5 के बाद एक आईपी पते के साथ अधिक पाठ या कोई पाठ नहीं हो सकता है। मुझे आईपी पते से लाइन के अंत तक सब कुछ चाहिए $ 5 के बाद कुछ भी होना चाहिए। मेरे मामले में, यह एक awk प्रोग्राम है, जो कि awk oneliner नहीं है, इसलिए इस समस्या को हल करना चाहिए। जब मैं पुरानी अच्छी दिखने वाली और सबसे अपवित्र लेकिन पूरी तरह से गलत उत्तर का उपयोग करके पहले 4 फ़ील्ड निकालने की कोशिश करता हूं:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'

यह गलत और बेकार प्रतिक्रिया करता है (मैंने प्रदर्शित करने के लिए [] जोड़ा]:

[    37.244.182.218 one two three]

इसके बजाय, यदि कट पॉइंट और awk तक कॉलम की चौड़ाई तय की जाती है, तो सही और काफी सरल उत्तर है:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218 one two three" | awk '{printf "[%s]\n", substr($0,28)}'

जो वांछित उत्पादन का उत्पादन करता है:

[37.244.182.218 one two three]

0

मुझे यह दूसरी संभावना मिल गई है, शायद यह उपयोगी भी हो सकती है ...

awk 'BEGIN {OFS=ORS="\t" }; {for(i=1; i<14; i++) print $i " "; print $NF "\n" }' your_file

नोट: 1. सारणीबद्ध डेटा और कॉलम $ 1 से $ 14 के लिए


0

कट का उपयोग करें:

cut -d <The character between characters> -f <number of first column>,<number of last column> <file name>

उदाहरण: यदि आपके पास है file1:car.is.nice.equal.bmw

भागो: cut -d . -f1,3 file1 छपेगाcar.is.nice


लगता है कि आपका समाधान पिछड़ा हुआ हो सकता है। कृपया प्रश्न शीर्षक की समीक्षा करें सभी * लेकिन * पहले तीन कॉलम
स्टीफन क्रैन

-1

यह पिछले कुछ उत्तरों से बहुत दूर नहीं है, लेकिन कुछ मुद्दों को हल करता है:

cols.sh:

#!/bin/bash
awk -v s=$1 '{for(i=s; i<=NF;i++) printf "%-5s", $i; print "" }'

जिसे आप अब एक तर्क के साथ कह सकते हैं जो शुरुआती कॉलम होगा:

$ echo "1 2 3 4 5 6 7 8 9 10 11 12 13 14" | ./cols.sh 3 
3    4    5    6    7    8    9    10   11   12   13   14

या:

$ echo "1 2 3 4 5 6 7 8 9 10 11 12 13 14" | ./cols.sh 7 
7    8    9    10   11   12   13   14

यह 1-अनुक्रमित है; यदि आप शून्य अनुक्रमित पसंद करते हैं, तो i=s + 1इसके बजाय का उपयोग करें ।

इसके अलावा, यदि आप आरंभिक सूचकांक और अंतिम सूचकांक के लिए तर्क करना चाहते हैं, तो फ़ाइल को इसमें बदलें:

#!/bin/bash
awk -v s=$1 -v e=$2 '{for(i=s; i<=e;i++) printf "%-5s", $i; print "" }'

उदाहरण के लिए:

$ echo "1 2 3 4 5 6 7 8 9 10 11 12 13 14" | ./cols.sh 7 9 
7    8    9

%-5sसंरेखित करता है 5-चरित्र चौड़ा स्तंभों के रूप में परिणाम; यदि यह पर्याप्त नहीं है, तो संख्या बढ़ाएँ या उपयोग करें %s(स्थान के साथ) इसके बजाय यदि आप संरेखण के बारे में परवाह नहीं करते हैं।


-1

AWK प्रिंटफ-आधारित समाधान जो% समस्या से बचता है, और इसमें अद्वितीय है कि यह प्रिंट करने के लिए 4 कॉलम से कम होने पर कुछ भी नहीं (कोई रिटर्न चरित्र नहीं) देता है:

awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'

परिक्षण:

$ x='1 2 3 %s 4 5 6'
$ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
%s 4 5 6
$ x='1 2 3'
$ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
$ x='1 2 3 '
$ echo "$x" | awk 'NF > 3 { for(i=4; i<NF; i++) printf("%s ", $(i)); print $(i) }'
$
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.