मल्टी-लाइन स्ट्रिंग को एकल अल्पविराम से अलग करना


95

मान लें कि मेरे पास निम्नलिखित स्ट्रिंग हैं:

something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

मैं इसे कैसे बदल सकता हूँ

+12.0,+15.5,+9.0,+13.5

बाश में?


आइए एक पल के लिए पीछे हटें और इस धागे को एक प्रोग्रामिंग भाषा के रूप में बैश के एक शानदार अभियोग पर विचार करें। स्कैला listOfStuff mkString ", ", या हास्केल केintercalate ", " listOfString
एफपी फ्रीली

जवाबों:


92

आप उपयोग कर सकते हैं awkऔर sed:

awk -vORS=, '{ print $2 }' file.txt | sed 's/,$/\n/'

या यदि आप एक पाइप का उपयोग करना चाहते हैं:

echo "data" | awk -vORS=, '{ print $2 }' | sed 's/,$/\n/'

इसे तोड़ने के लिए:

  • awk खेतों में टूटे हुए डेटा को संभालने में महान है
  • -vORS=,"आउटपुट रिकॉर्ड विभाजक" को सेट करता है ,, जो कि आप चाहते थे
  • { print $2 }awkहर रिकॉर्ड (लाइन) के लिए दूसरा क्षेत्र प्रिंट करना बताता है
  • file.txt आपका फ़ाइल नाम है
  • sedबस पीछे छूट ,जाता है और इसे एक नई पंक्ति में बदल देता है (यदि आप कोई नई रेखा नहीं चाहते हैं, तो आप ऐसा कर सकते हैं s/,$//)

1
awk: अमान्य -v विकल्प :(
मार्सेलस वालेस

6
-V और ORS =, (मेरे लिए, ओएक्सएक्स पर) के बीच एक स्थान जोड़ें
ग्राहम पी हीथ

पाइप को अलग करने के लिए एक ही कमांड कैसे करें? awk -v ORS=| '{ print $1 }' DCMC.rtf | sed 's/,$/\n/'मुझे एक त्रुटि मिल रही है
योगेश

2
अजीब बात है, जब मैं ऐसा करने की कोशिश करता हूं, तो आउटपुट खाली होता है।
शाश्वत

1
मुझे लगता है कि पाइपेड संस्करण के लिए यह होना चाहिए {print $1}अन्यथा मुझे केवल आउटपुट में कॉमा मिल रहा है
प्रेज़ेमिसकोव चेकोवस्की

162

साफ और सरल:

awk '{print $2}' file.txt | paste -s -d, -

3
यह यहाँ सबसे अच्छा जवाब है, और स्पष्ट रूप से ऐसा करने का सही तरीका है
forresthopkinsa

मैं एकल / डबल उद्धरण के साथ हर मूल्यों को कैसे उद्धृत करूं?
हुसैन

1
@Hussaincat thing | awk -F',' '{ print "'\''" $7 "'\' '" }' | paste -s -d ','
starbeamrainbowlabs

,'सीमांकक के रूप में कैसे उपयोग करें ?
कसुन सियामलबिपतिया

यदि स्ट्रिंग में कोई CRLF हैं, तो Windows केdos2unix नए सिरे (उदाहरण के लिए ) का उपयोग करना याद रखें ।
बोवी


10
$ awk -v ORS=, '{print $2}' data.txt | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

$ cat data.txt | tr -s ' ' | cut -d ' ' -f 2 | tr '\n' ',' | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

चियर्स, के बारे में है, तो awk के लिए इनपुट मानक इनपुट के माध्यम से था क्या (बस डाल function | awk...अपने उदाहरण में?
एलेक्स Coplan



8

यह आपके लिए काम कर सकता है:

cut -d' ' -f5 file | paste -d',' -s
+12.0,+15.5,+9.0,+13.5

या

sed '/^.*\(+[^ ]*\).*/{s//\1/;H};${x;s/\n/,/g;s/.//p};d' file
+12.0,+15.5,+9.0,+13.5

या

sed 's/\S\+\s\+//;s/\s.*//;H;$!d;x;s/.//;s/\n/,/g' file

फ़ाइल में प्रत्येक पंक्ति के लिए; पहले क्षेत्र और रिक्त स्थान को काटें, दूसरे क्षेत्र का अनुसरण करते हुए शेष रेखा को काटें और होल्ड स्थान पर रखें। सभी लाइनों को हटाएं, जहां हम अंतिम स्थान को स्वैप करते हैं और शुरू में शुरू की गई नई लाइन को हटाने के बाद, सभी नई लाइनों को परिवर्तित करें ,

NB लिखा जा सकता है:

sed 's/\S\+\s\+//;s/\s.*//;1h;1!H;$!d;x;s/\n/,/g' file

4

आप उपयोग कर सकते हैं grep:

grep -o "+\S\+" in.txt | tr '\n' ','

जो स्ट्रिंग के साथ शुरू होता है +, उसके बाद किसी भी स्ट्रिंग को पाता है \S\+, फिर नई लाइन वर्णों को कॉमा में परिवर्तित करता है। यह बड़ी फ़ाइलों के लिए बहुत जल्दी होना चाहिए।


4

इस आसान कोड को आज़माएं:

awk '{printf("%s,",$2)}' File1

3

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

sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*"\1,"'
sedClearLastComma='s"\(.*\),$"\1"'
cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"

अच्छी बात यह है कि newline "\ n" वर्णों को हटाने का आसान हिस्सा है!

संपादित करें: sed के साथ एक ही लाइन में लाइनों को जोड़ने का एक और शानदार तरीका यह है: यहां|sed ':a;N;$!ba;s/\n/ /g' से मिला ।


यह EDIT भयानक है - +1!
जोजी

2

शुद्ध बैश में लिखा एक समाधान:

#!/bin/bash

sometext="something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)"

a=()
while read -r a1 a2 a3; do
    # we can add some code here to check valid values or modify them
    a+=("${a2}")
done <<< "${sometext}"
# between parenthesis to modify IFS for the current statement only
(IFS=',' ; printf '%s: %s\n' "Result" "${a[*]}")

परिणाम: + 12.0, + 15.5, + 9.0, + 13.5


2

जाग के साथ इस सरल समाधान नहीं देखा है

awk 'b{b=b","}{b=b$2}END{print b}' infile

0

पर्ल के साथ:

fg@erwin ~ $ perl -ne 'push @l, (split(/\s+/))[1]; END { print join(",", @l) . "\n" }' <<EOF
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
EOF

+12.0,+15.5,+9.0,+13.5

0

आप इसे दो सेड कॉल के साथ भी कर सकते हैं:

$ cat file.txt 
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
$ sed 's/^[^:]*: *\([+0-9.]\+\) .*/\1/' file.txt | sed -e :a -e '$!N; s/\n/,/; ta'
+12.0,+15.5,+9.0,+13.5

पहला sed कॉल निर्बाध डेटा को हटाता है, और दूसरा सभी लाइनों से जुड़ता है।


0

आप इस तरह भी प्रिंट कर सकते हैं:

बस awk: का उपयोग कर printf

bash-3.2$ cat sample.log
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

bash-3.2$ awk ' { if($2 != "") { if(NR==1) { printf $2 } else { printf "," $2 } } }' sample.log
+12.0,+15.5,+9.0,+13.5

0

एक और पर्ल समाधान, डेन फेगो के जाग के समान है:

perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'

-a perl को इनपुट लाइन को @F सरणी में विभाजित करने के लिए कहता है, जिसे 0 से शुरू किया जाता है।


0

अच्छी तरह से सबसे मुश्किल हिस्सा शायद दूसरे "कॉलम" का चयन कर रहा है क्योंकि मुझे एक के रूप में एक से अधिक रिक्त स्थान का इलाज करने का एक आसान तरीका नहीं पता होगा। बाकी के लिए यह आसान है। बैश प्रतिस्थापन का उपयोग करें।

# cat bla.txt
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

# cat bla.sh
OLDIFS=$IFS
IFS=$'\n'
for i in $(cat bla.txt); do
  i=$(echo "$i" | awk '{print $2}')
  u="${u:+$u, }$i"
done
IFS=$OLDIFS
echo "$u"

# bash ./bla.sh
+12.0, +15.5, +9.0, +13.5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.