出力をcsv形式でフォーマットする必要がある

出力をcsv形式でフォーマットする必要がある

これはabc.txtファイルです

NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"
NAME="MARK" StartTime="14:11:26.710583" TotalElapsedTime="0" Pool="10" ThreadsReached="0"

abc.csv で以下の形式の出力が必要です

NAME    StartTime   TotalElapsedTime    Pool    ThreadsReached
MARK    14:11:26.710583     0       10      0
MARK    14:11:26.710583     0       10      0

答え1

基本的なCSV形式では,フィールド区切りとしてカンマが想定されているため、次のGNUsedアプローチ:

sed -e '1iNAME,StartTime,TotalElapsedTime,Pool,ThreadsReached' -e 's/[^=]*="\([^"]*\)"/\1,/g; s/,$//g' file

出力:

NAME,StartTime,TotalElapsedTime,Pool,ThreadsReached
MARK,14:11:26.710583,0,10,0
MARK,14:11:26.710583,0,10,0

1i- 挿入ヘッダファイルの最初の行の前の行

s/[^=]*="\([^"]*\)"/\1,/g- すべての属性値を抽出する

答え2

while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift; N=$#
   for arg
   do
      set -- ${1+"$@"} "$(expr " $arg" : ' "\(.*\)"')"
   done
   shift "$N"; IFS=,; echo "$*"
done < abc.txt

while IFS= read -r l; do
   set -f; IFS==; set -- $l; shift
   while case ${#} in 1 ) break ;; esac; do
      expr " $1" : ' "\(.*\)"'
      shift
   done | tr \\n ,; expr " $*" : '.*"\(.*\)"'
done < abc.txt

perl -lne '$,=",";
   print /(?:^|\h)\K[^=]*/g if $. == 1;
   print /="([^"]*)"/g;
' abc.txt

説明

  • Perl コードでは、最初の行から、左側に水平の空白または行の先頭がある文字/(?:^|\h)\K[^=]*/gの連続を取得するように読み取られる正規表現を使用してフィールド名を抽出します。次に、これらはコンマのセットを使用して印刷されます。non=\h^OFS $,
  • すべての行 (最初の行も含む) について、正規表現を使用してフィールド値を抽出します。正規表現は、/="([^"]*)"/g等号の左側に隣接する二重引用符で囲まれた文字列 (エスケープされた二重引用符がないと仮定) を抽出します。これらの値のコレクションは、stdoutと結合されますOFS
  • ループ ソリューションの場合while、最初に単語を分割せずに行をそのまま読み取ります。次に、IFS を に設定し=、最初のフィールドを拒否します。これで、すべてのフィールドの形式が になります。"..."...次に、ユーティリティを使用してexpr、二重引用符内の値を具体化し、配列に配置します$@。ループの最後で、for元の要素 ( $N) を削除すると、残ったものが必要なものになります。最後に、IFS をカンマに設定して を展開することにより、それらがカンマで結合されます$*

関連情報