次の文字列があるとしましょう:
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
バッシュ?
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
にすべてのレコード(行)の2番目のフィールドを印刷するように指示しますfile.txt
はファイル名ですsed
は末尾の,
を取り除き、改行に変換します(改行が不要な場合は、s/,$//
を実行できます)クリーンでシンプル:
awk '{print $2}' file.txt | paste -s -d, -
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
これも動作するはずです
awk '{print $2}' file | sed ':a;{N;s/\n/,/};ba'
これはあなたのために働くかもしれません:
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
ファイルの各行。最初のフィールドとそれに続くスペースを切り取り、2番目のフィールドに続く行の残りを切り取り、ホールドスペースに追加します。ホールドスペースにスワップする最後の行を除くすべての行を削除し、最初に導入された改行を削除した後、すべての改行を,
に変換します。
N.B.書くことができます:
sed 's/\S\+\s\+//;s/\s.*//;1h;1!H;$!d;x;s/\n/,/g' file
awk 1ライナー
$ awk '{printf (NR>1?",":"") $2}' file
+12.0,+15.5,+9.0,+13.5
grep
を使用できます:
grep -o "+\S\+" in.txt | tr '\n' ','
+
で始まり、その後に任意の文字列\S\+
が続く文字列を検索し、改行文字をコンマに変換します。これは、大きなファイルの場合はかなり速いはずです。
これを試して:
sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*"\1,"'
sedClearLastComma='s"\(.*\),$"\1"'
cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"
良いのは、改行「\ n」文字を削除する簡単な部分です!
編集:sedを使用して行を1行に結合するもう1つの優れた方法は、|sed ':a;N;$!ba;s/\n/ /g'
を here から取得します。
純粋な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
Awkでこの簡単なソリューションを見ないでください
awk 'b{b=b","}{b=b$2}END{print b}' infile
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
また、2つの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.]\+\) .*/\1/' file.txt | sed -e :a -e '$!N; s/\n/,/; ta'
+12.0,+15.5,+9.0,+13.5
最初のsed呼び出しは、関心のないデータを削除し、2番目の呼び出しはすべての行を結合します。
Dan Fegoのawkに似た別のPerlソリューション:
Perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'
-a
は、入力行を0から始まるインデックス付きの@F配列に分割するようPerlに指示します。
複数のスペースを1つとして扱う簡単な方法がわからないので、最も難しい部分はおそらく2番目の「列」を選択することです。残りは簡単です。 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 $2}')
u="${u:+$u, }$i"
done
IFS=$OLDIFS
echo "$u"
# bash ./bla.sh
+12.0, +15.5, +9.0, +13.5
次のように印刷することもできます。
ちょうど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