약 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인칭
삼[이메일 보호됨]<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을 언급했는지 알아야 합니다. 데이터가 원래 스프레드시트에 있는 경우 직접 읽는 데 사용됩니까? Excel 또는 데이터를 추출하는 Open/Libre Office와 같은 Perl 모듈에서 제공한 샘플 데이터로 작동합니다.
이는 원하는 수의 입력 파일을 처리할 수 있습니다.
공백 대신 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)의 두 복사본을 입력으로 사용하며 파이프를 통해 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
하거나 (실행 중인 항목에 따라) 루프를 사용하지 않고 실행 중인 명령에 모든 파일 이름 인수를 전달하기만 하면 됩니다.