훌륭합니다. 계정을 교환하고 빼기 기호를 제거하는 방법입니다.
파일에는 다음과 같은 여러 트랜잭션이 포함되어 있습니다.
입력하다:
2018/01/08 * Aldi
; MD5Sum: a587a267588505265ae437c43c978886
; CSV: 2018-1-8,aldi,40.85
Expenses:Groceries
Expenses:Unknown USD -40.85
; :Groceries:
예상 출력:
2018/01/08 * Aldi
; MD5Sum: a587a267588505265ae437c43c978886
; CSV: 2018-1-8,aldi,40.85
Expenses:Groceries USD 40.85
Expenses:Unknown
; :Groceries:
맨 오른쪽의 금액은 무효화되었으며 가 Expenses:Groceries
아닌 에 추가되었습니다 Expenses:Unknown
.
답변1
Perl을 사용하는 가장 간단한 방법은 모든 데이터를 한 번에 읽고 섹션으로 나눈 다음(아마도 줄 시작 부분의 4자리 숫자로 시작) 각 섹션에서 개별적으로 작업하는 것입니다. 질문에 데이터가 완전히 지정되지 않았기 때문에 데이터에 대한 가정이 이루어졌습니다.
#!/usr/bin/perl
use strict;
my $data = join("", <>);
my @stanzas = split(/^(?=\d{4})/m, $data);
foreach my $st (@stanzas){
if($st =~ m/Expenses:(?!Unknown)\S+\s*$/m){
if($st =~ m/Expenses:Unknown\s+(USD\s+-[0-9.]+)/){
my $amount = $1;
$amount =~ s/-//;
$st =~ s/Expenses:(?!Unknown)(\S+)(\s*)$/Expenses:$1 $amount/m;
$st =~ s/Expenses:Unknown(\s+USD\s+-[0-9.]+)/Expenses:Unknown/;
}
}
}
print join("", @stanzas);
여기서 split()
함수는 예측 모드를 사용하여 (?=)
전체 입력을 4자리로 시작하는 줄로 분할합니다.
각 섹션에 대해 Expenses 뒤에 Unknown이 없고 뒤에 공백이 없고 공백만 있고 Unknown 뒤에 음수가 오는 경우 해당 숫자와 이전 USD를 캡처하고 음수 기호를 제거합니다.
결과는 고정된 공간을 가진 첫 번째 일치 행으로 대체되고 알 수 없는 행에서는 제거됩니다. 이를 개별적으로 수행하면 두 필드가 섹션 내에서 다른 순서로 배치될 수 있습니다.
마지막으로 섹션이 연결되어 인쇄됩니다.
답변2
단락 모드에서 Perl을 사용하여 한 번에 한 단락을 처리하고 알 수 없는 필드에서 달러 비용을 추출하여 다른 비용 행에 붙여넣습니다.
$ perl -p00 -e '
my @A = /^\h+Expenses:Unknown(\h+USD\h+)-(\d+\.\d+)$/m;
s/^\h+Expenses:\K((Unknown)\h|\S+).*$/$2 ? $2 : "$1@A"/gem if @A;
' file