Bash превращение многострочной строки в одну запятую
допустим, у меня есть следующая строка:
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
в bash?
16 ответов:
можно использовать
awk
иsed
:awk -vORS=, '{ print }' file.txt | sed 's/,$/\n/'
или если вы хотите использовать трубы:
echo "data" | awk -vORS=, '{ print }' | sed 's/,$/\n/'
чтобы разбить его:
awk
отлично справляется с обработкой данных, разбитых на поля-vORS=,
устанавливает "выходной разделитель записей" в,
, который является то, что вы хотели{ print }
говоритawk
для печати второго поля для каждой записи (строки)file.txt
ваш имя файлаsed
просто избавляется от трейлинг,
и превращает его в новую строку (если вы не хотите новой строки, вы можете сделатьs/,$//
)
$ awk -v ORS=, '{print }' 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
Это может сработать для вас:
cut -d' ' -f5 file | paste -d',' -s +12.0,+15.5,+9.0,+13.5
или
sed '/^.*\(+[^ ]*\).*/{s///;H};${x;s/\n/,/g;s/.//p};d' file +12.0,+15.5,+9.0,+13.5
попробуйте это:
sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*","' sedClearLastComma='s"\(.*\),$""' cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"
хорошая вещь-это легкая часть удаления символов новой строки "\n"!
EDIT: еще один отличный способ объединить строки в одну строку с sed-это:
|sed ':a;N;$!ba;s/\n/ /g'
получил от здесь.
можно использовать
grep
:grep -o "+\S\+" in.txt | tr '\n' ','
который находит строку, начинающуюся с
+
, за которым следует любая строка\S\+
, затем преобразуйте новые символы строки в запятые. Это должно быть довольно быстро для больших файлов.
С 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
вы также можете сделать это с двумя вызовами sed:
$ 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.]\+\) .*//' file.txt | sed -e :a -e '$!N; s/\n/,/; ta' +12.0,+15.5,+9.0,+13.5
первый вызов sed удаляет неинтересные данные, а второй соединяет все строки.
вы также можете напечатать так:
просто 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( != "") { if(NR==1) { printf } else { printf "," } } }' sample.log +12.0,+15.5,+9.0,+13.5
другое решение Perl, похожее на awk Дана Фего:
perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'
-a
говорит perl разделить входную строку в массив @F, который индексируется, начиная с 0.
решение, написанное в чистом виде 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[*]}")
результат: +12.0,+15.5,+9.0,+13.5
Ну, самая сложная часть, вероятно, выбирает второй "столбец", так как я не знаю простого способа обработки нескольких пространств как одного. В остальном все просто. Использовать bash замен.
# 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 }') u="${u:+$u, }$i" done IFS=$OLDIFS echo "$u" # bash ./bla.sh +12.0, +15.5, +9.0, +13.5