Let's say I have the following string:
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)
How do I turn that into simply
+12.0,+15.5,+9.0,+13.5
in bash?
Well the hardest part probably is selecting the second "column" since I wouldn't know of an easy way to treat multiple spaces as one. For the rest it's easy. Use bash substitutions.
# 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
Another Perl solution, similar to Dan Fego's awk:
perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'
-a
tells perl to split the input line into the @F array, which is indexed starting at 0.
Try this easy code:
awk '{printf("%s,",$2)}' File1
With perl:
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
This might work for you:
cut -d' ' -f5 file | paste -d',' -s
+12.0,+15.5,+9.0,+13.5
or
sed '/^.*\(+[^ ]*\).*/{s//\1/;H};${x;s/\n/,/g;s/.//p};d' file
+12.0,+15.5,+9.0,+13.5
or
sed 's/\S\+\s\+//;s/\s.*//;H;$!d;x;s/.//;s/\n/,/g' file
For each line in the file; chop off the first field and spaces following, chop off the remainder of the line following the second field and append to the hold space. Delete all lines except the last where we swap to the hold space and after deleting the introduced newline at the start, convert all newlines to ,
's.
N.B. Could be written:
sed 's/\S\+\s\+//;s/\s.*//;1h;1!H;$!d;x;s/\n/,/g' file
Clean and simple:
awk '{print $2}' file.txt | paste -s -d, -
awk one liner
$ awk '{printf (NR>1?",":"") $2}' file
+12.0,+15.5,+9.0,+13.5
Don't seen this simple solution with awk
awk 'b{b=b","}{b=b$2}END{print b}' infile
You can also print like this:
Just awk: using 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
This should work too
awk '{print $2}' file | sed ':a;{N;s/\n/,/};ba'
cat data.txt | xargs | sed -e 's/ /, /g'
$ 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
A solution written in pure Bash:
#!/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[*]}")
Result: +12.0,+15.5,+9.0,+13.5
You can also do it with two sed calls:
$ 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
First sed call removes uninteresting data, and the second join all lines.
Yet another AWK solution
Run
awk '{printf "%s", $c; while(getline){printf "%s%s", sep, $c}}' c=2 sep=','
to use the 2nd column to form the list separated by commas. Give the input as usual in standard input or as a file name argument.
You can use grep
:
grep -o "+\S\+" in.txt | tr '\n' ','
which finds the string starting with +
, followed by any string \S\+
, then convert new line characters into commas. This should be pretty quick for large files.
try this:
sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*"\1,"'
sedClearLastComma='s"\(.*\),$"\1"'
cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"
the good thing is the easy part of deleting newline "\n" characters!
EDIT: another great way to join lines into a single line with sed is this: |sed ':a;N;$!ba;s/\n/ /g'
got from here.
Source: Stackoverflow.com