
これは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 をカンマに設定して を展開することにより、それらがカンマで結合されます$*
。