it-swarm.com.de

Mehrzeilige Zeichenfolge durch Kommas getrennt

Nehmen wir an, ich habe folgende Zeichenfolge:

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)

Wie mache ich das einfach?

+12.0,+15.5,+9.0,+13.5

in bash?

71
Alex Coplan

Sie können awk und sed verwenden:

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

Oder wenn Sie eine Pfeife verwenden wollen:

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

Um es aufzubrechen:

  • awk eignet sich hervorragend für den Umgang mit Daten, die in Felder unterteilt sind
  • -vORS=, setzt das "Ausgabedatentrennzeichen" auf ,, was Sie wollten
  • { print $2 } weist awk an, das zweite Feld für jeden Datensatz (Zeile) zu drucken.
  • file.txt ist Ihr Dateiname
  • sed entfernt einfach den nachlaufenden , und verwandelt ihn in eine Newline (wenn Sie keine Newline wollen, können Sie s/,$//)
70
Dan Fego

Sauber und einfach:

awk '{print $2}' file.txt | paste -s -d, -
119
Mattias Ahnberg
$ 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
9
kev

Das sollte auch funktionieren

awk '{print $2}' file | sed ':a;{N;s/\n/,/};ba'
8
jaypal singh
cat data.txt | xargs | sed -e 's/ /, /g'
7

Das könnte für Sie funktionieren:

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

oder

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

awk ein Liner

$ awk '{printf (NR>1?",":"") $2}' file

+12.0,+15.5,+9.0,+13.5
4
batMan

versuche dies:

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

die gute Sache ist der einfache Teil des Löschens von "\ n" Newline-Zeichen!

BEARBEITEN: Eine weitere gute Möglichkeit, Zeilen mit sed zu einer einzigen Zeile zu verbinden, lautet: |sed ':a;N;$!ba;s/\n/ /g' kam von here .

3
Aquarius Power

Sie können grep verwenden:

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

die Zeichenfolge beginnt mit +, gefolgt von einer beliebigen Zeichenfolge \S\+, und konvertiert dann neue Zeilenzeichen in Kommas. Dies sollte für große Dateien ziemlich schnell sein.

2
kenorb

Diese einfache Lösung mit awk habe ich nicht gesehen

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

Eine in pure Bash geschriebene Lösung:

#!/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[*]}")

Ergebnis: + 12,0, + 15,5, + 9,0, + 13,5

1

Mit Perl:

[email protected] ~ $ 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
fge

Sie können es auch mit zwei sed-Aufrufen machen:

$ 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

Der erste sed-Anruf entfernt uninteressante Daten und der zweite verbindet alle Zeilen.

0
elias

Eine weitere Perl-Lösung, ähnlich wie Dan Fegos awk:

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

-a weist Perl an, die Eingabezeile in das @F-Array aufzuteilen, das ab 0 indiziert wird.

0
Chris Koknat

Am schwierigsten ist es wahrscheinlich, die zweite "Spalte" auszuwählen, da ich keine einfache Möglichkeit kennen würde, mehrere Leerzeichen als eine zu behandeln. Für den Rest ist es einfach. Verwenden Sie Bash-Substitutionen.

# 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
0
Marki

Sie können auch so drucken:

Einfach awk: mit 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
user982733