約100,000個のファイルに次のヘッダーがあります。各行を個別に抽出し、各レコードをExcelにマージしたので、時間が足りなくなり、データを抽出する便利な方法を探しています。
X-RSMF-Generator:RSMFジェネレータのサンプルライブラリ
X-RSMFバージョン:1.0.0
X-RSMFイベント数:53
X-RSMF-開始日:2022-09-20T04:33:11-04:00
X-RSMF終了日:2022-09-20T16:47:56-04:00
X-RSMF-グループID:GRP000000118
X-RSMF補助グループID:GRP000000118_D_20220920
X-RSMFインクルードが削除されました:間違った
X-RSMF-アプリケーション:ネイティブメッセージ
X-RSMF参加者:1人称<5156242756> 2人称、2人称
サム[Eメール保護]<21243210277> 4人*** <345278652345>
MIMEバージョン:1.0
すべてのファイルにすべての行が存在するわけではなく、最後のフィールドに複数の行を含めることができます。 MIME バージョン: 1.0 - 利用できるようです。MIMEバージョン:1.0停止で。また、各項目行のデータのみが必要です。 ":" (コロン空白) 前の内容はすべてフィールドヘッダーなので無視できます。
私は各ラインとパイプをAWKに接続できると思いながらsedを使い始めました。各柱を作ります。
#!/bin/sh
shopt -s nullglob
FILES=/mnt/c/Temp/rsmf/*.rsmf
for f in $FILES
do
#echo "Processing $f"
sed -rn \
-e '/^X-RSMF-BeginDate:/{
s/X-RSMF-BeginDate: //
s/T/ /
s/-0[45]:00/ /
s/X-RSMF-Application://
h
#p
}' \
-e '/^X-RSMF-EndDate:/{
s/X-RSMF-EndDate: //
s/T/ /
s/-0[45]:00/ /
H
#p
}' \
-e '/^X-RSMF-GroupID:/{
s/X-RSMF-GroupID: //
H
x
s/\r\n//gp
}' \
$f
done
結果 -
2022-10-05 12:54:27 2022-10-05 12:54:27 GRP000000001
2022-10-05 11:48:18 2022-10-05 11:48:18 GRP000000002
この問題を議論する前に、この特定のプロジェクトのベストプラクティスとケースに関するアドバイスを求めたいと思います。
アイデア? ?
答え1
そしてアッ:
awk -F': ' 'BEGIN{ORS=" "}$1=="MIME-Version"{exit}{print $2}END{print "\n"}' file
答え2
以下はやや昔ながらの無差別的なアプローチです。おそらくより良い方法があります。 (しかし、あなたのデータについてもっと知っておく必要があり、なぜExcelに言及したのかを知る必要があります。サンプルデータとして機能します。
これにより、必要な数の入力ファイルを処理できます。
スペースの代わりにTAB(\t
またはCtrl-Iまたは)を出力フィールド区切り文字として使用するように作成されました。^I
フィールドデータにスペースを含めることができるため、。
#!/usr/bin/perl
while (<>) {
chomp;
s/^\s*|\s*$//g; # strip any leading and trailing whitespace
next if /^$/; # ignore all blank lines
# split input line into @F array
# $F[0] will contain the field name and
# $F[1] will contain the field data
# The field separator is a quite-forgiving zero-or-more spaces followed by
# a colon followed by one-or-more spaces. This should cope with most minor
# variants caused by manual extraction from Excel.
my @F = split /\s*:\s+/;
# print the data at end of each input record (file)
if (/^MIME-Version/) {
# add space-separated @participants array to end of @record array
push @record, join(" ", @participants);
# print @record array, tab-separated
print join("\t", @record), "\n";
# clear both arrays, ready for next input file
@record=();
@participants=();
next;
};
# fix up the date format
if (/^X-RSMF-(Begin|End)Date/) {
$F[1] =~ s/T/ /;
$F[1] =~ s/-0[45]:00$//;
};
if (/^X-RSMF-Participants/) {
# participants need to be handled differently because this field can
# be multi-line. Store in a separate @participants array
push @participants, $F[1];
} elsif ($#F == 0) {
# lines without a field name get added to @participants array
push @participants, $_;
} else {
# all other fields get added to @record array
push @record, $F[1];
}
}
たとえば、ファイルに保存してrsmf2tab.pl
実行可能にしてからchmod +x rsmf2tab.pl
実行します。
./rsmf2tab.pl /mnt/c/Temp/rsmf/*.rsmf
または、.rsmfファイルが複数のサブディレクトリにある場合:
find /mnt/c/Temp/rsmf/ -name '*.rsmf' -exec /path/to/rsmf2tab.pl {} +
サンプル出力は、サンプルデータ(file1.rsmfとfile2.rsmfなど)の2つのコピーを入力として使用し、パイプを介してタブを次のcat -A
ように表示します^I
。
$ ./rsmf2tab.pl *.rsmf | cat -A
RSMF Generator Sample Library^I1.0.0^I53^I2022-09-20 04:33:11^I2022-09-20 16:47:56^IGRP000000118^IGRP000000118_D_20220920^IFalse^INative Messages^IPerson One <5156242756> Person two, Person three [email protected] <21243210277> Person four <345278652345>$
RSMF Generator Sample Library^I1.0.0^I53^I2022-09-20 04:33:11^I2022-09-20 16:47:56^IGRP000000118^IGRP000000118_D_20220920^IFalse^INative Messages^IPerson One <5156242756> Person two, Person three [email protected] <21243210277> Person four <345278652345>$
しかし、あなたは本物FILE=/mnt/c/Temp/rsmf/*.rsmf
私はもはやあなたの後継者になりたくありませんfor f in $FILES
。ファイルに空白文字が含まれていると中断されます。とにかく、これは必要ありません。単に実行したりfor f in /mnt/c/Temp/rsmf/*.rsmf
(実行中の項目に応じて)ループを使用せずに、実行中のコマンドにすべてのファイル名引数を渡すだけです。