다음 계정이 포함된 텍스트 파일이 있습니다.
입력 샘플
Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180
시작 부분의 숫자를 무시하거나 첫 번째 단어에 연결하고 싶습니다. 그런 다음 첫 번째 단어를 대시/하이픈으로 연결하고 날짜를 입력한 다음 단어를 입력합니다. 숫자를 추가하므로 새 줄을 제외하고 공백을 제거하십시오.
Linux 노트북에 쉽게 설치하고 실행할 수 있는 스크립트, perl/php, bash, awk, sed 등이 될 수도 있습니다.
출력 샘플
Paid;100;15/02/2022;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
이것을 스프레드시트로 가져오고 싶으므로 다른 방법도 가능합니다. 약 300줄이 있습니다.
이전에 무엇을 시도했습니까? 스프레드시트를 사용하여 이미지 및 이미지-텍스트 변환기에서 얻은 데이터를 정리합니다.
또한 notepad++ 및 열 선택을 사용해 보았습니다. 나는 빨리 AWK를 배우려고 노력했다. 나는 Java를 알고 있지만 시간이 오래 걸립니다. 답변을 받은 후 몇 가지 사실을 배웠습니다.
- 줄 번호가 있는 경우 이를 유지하면 awk를 사용할 때 어떤 줄이 누락되었는지 파악하는 데 도움이 됩니다. AS는 건너뛴 줄에 대한 경고 없이 출력을 제공합니다. 어쩌면 그것을 우회하는 설정일 수도 있지만 확실하지 않습니다.
- csv, 스프레드시트 또는 PDF 형식의 계정은 항상 요청되며 이미지는 허용되지 않습니다!
우리 계정의 친구로부터 받은 이미지에 이미지를 텍스트로 실행하여 입력을 받습니다.
답변1
perl -pe 's/(?:^[0-9]+|[^0-9])\K (?=[^0-9])/-/g;
s/ /;/g
' -- file
-p
입력을 한 줄씩 읽고 처리 후 각 줄을 인쇄합니다.- 첫 번째 교체는 Lookaround 어설션을 사용합니다.문자열 시작 부분에 공백 앞에 숫자가 있거나, 숫자는 아니지만 뒤에 숫자가 없으면 공백을 대시로 바꿉니다.;
- 두 번째 대체는 나머지 공백을 세미콜론으로 대체합니다.
마지막 줄 뒤의 두 공백이 오타가 아닌 경우 두 번째 교체를 변경하여 인접한 모든 공백을 단일 세미콜론으로 교체 50
해야 합니다 .s/ +/;/g
답변2
이제 답을 얻었으니...
세 번째 인수로 GNU awk를 사용하십시오 match()
.
awk -v OFS=';' '
match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
$0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
gsub(/\s+/,"-")
print
}
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
위의 내용은 입력 형식이 다음과 같다고 가정합니다.
<anything1> <integer1> <date>[ <anything2>] <integer2>
(.*\S) ([0-9]+) ^ ( (.*\S))? ([0-9]+)
|
(([0-9]{2}\/){2}[0-9]{4})
필드 사이에 개행이 아닌 공백이 있을 수 있는 경우, anything
내부 필드는 <...>
항상 공백이 아닌 것으로 끝나지만 공백이나 다른 문자를 포함할 수 있고, 정수 앞에 오는 날짜 문자열은 포함될 수 없으며 anything1
, [ <anything2>]
선택 사항이며 원하는 경우 출력이 다음과 같다고 가정해 보겠습니다.
<anything1>;<integer1>;<date>;<anything2>;<integer2>
이는 Paid;100;15/02/2022;3000
예상 출력에서 실제로 Paid;100;15/02/2022;;3000
다음과 같아야 함을 의미합니다. 각 출력 행에는 OP가 원한다고 말한 대로 스프레드시트를 가져오는 데 사용되는 필드 수가 동일해야 합니다.
\S
정규식 시작 부분에 단일을 사용하고 원래 예상했던 대로 배열 요소를 채우는 대신 substr()
헤더 문자열을 가져오는 데 사용하고 있으며 이것이 실패할 것이라는 것을 깨달았으므로 질문에 게시된 예제 입력을 사용하겠습니다. 주어진 입력, 예를 들어:anything
(.*\S)
Paid 100 15/02/2022 foo 100 15/02/2022 3000
여기서 줄에 2개의 날짜가 있고 두 번째 날짜 주위의 문자열이 나머지 정규식과 일치합니다. 예를 들어 이 수정된 입력과 맨 아래에 있는 문제의 줄은 다음과 같습니다.
$ cat file
Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180
Paid 100 15/02/2022 foo 100 15/02/2022 3000
(.*\S)
정규식 시작 부분에 사용하는 경우 바람직하지 않은 마지막 출력 줄에 유의하세요.
$ awk -v OFS=';' '
match($0,/(.*\S)\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
$0 = a[1] OFS a[2] OFS a[3] OFS a[6] OFS a[7]
gsub(/\s+/,"-")
print
}
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
Paid-100-15/02/2022-foo;100;15/02/2022;;3000
제안된 스크립트를 사용하여 출력을 수정합니다.
$ awk -v OFS=';' '
match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
$0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
gsub(/\s+/,"-")
print
}
' file
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
Paid;100;15/02/2022;foo-100-15/02/2022;3000
댓글의 피드백을 기반으로 편집하세요. 정규식과 일치하지 않는 줄을 기록하세요.
awk -v OFS=';' '
match($0,/\S\s+([0-9]+)\s+(([0-9]{2}\/){2}[0-9]{4})(\s+(.*\S))? ([0-9]+)$/,a) {
$0 = substr($0,1,RSTART) OFS a[1] OFS a[2] OFS a[5] OFS a[6]
gsub(/\s+/,"-")
print
next
}
{ print > "/dev/stderr" }
' file 2>unmatched.log
답변3
sed -E 's,([^0-9 ]) +([^0-9 ]),\1-\2,g
s,^([0-9]+) +,\1-,g
s, +,;,g
'
답변4
사용행복하다(이전 Perl_6)
먼저 구문 분석할 모든 행을 얻을 수 있는지 확인하십시오.
~$ raku -ne '.match(/ ^ \d* \s? <.alpha>+ \s \d+ \s [ \d**2 \/ \d**2 \/ \d**4 ] \s [[<.graph>+]+ % " " \s]? \d+ $ /).say;' file
위의 내용은 Perl 프로그래밍 언어 제품군 중 유니코드를 지원하는 Raku의 한 가지 접근 방식입니다. 복잡한 정규식 문제로 시작하기 때문에 처음부터 끝까지 모든 줄이 올바르게 구문 분석되는 것을 보는 것이 가장 좋습니다 /^ … $/
. ( raku -pe 's:g/\s+/ /;'
먼저 공백 정규화와 같은 작업을 실행 해야 할 수도 있습니다 ). 위 코드는 Nil
OP의 결과인 올바르게 구문 분석되지 않은 행을 반환합니다.빈 정규화데이터:
입력 예:
Paid 100 15/02/2022 3000
recd 50 15/02/2022 nelur trip 3050
PAID 80 25/03/2022 Adjusted towards trip 3130
14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180
구문 분석 라인:
「Paid 100 15/02/2022 3000」
「recd 50 15/02/2022 nelur trip 3050」
「PAID 80 25/03/2022 Adjusted towards trip 3130」
「14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180」
이제 모든 행이 처음부터 끝까지 구문 분석되고 일치하는 요소를 캡처할 수 있음을 알 수 있습니다. 캡처를 나타내려면 괄호를 사용하십시오. Raku 캡처는 다음으로 시작됩니다 $0
.
~$ raku -ne '.match(/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $ /).say;' file
「Paid 100 15/02/2022 3000」
0 => 「Paid」
1 => 「100」
2 => 「15/02/2022」
4 => 「3000」
「recd 50 15/02/2022 nelur trip 3050」
0 => 「recd」
1 => 「50」
2 => 「15/02/2022」
3 => 「nelur」
3 => 「trip」
4 => 「3050」
「PAID 80 25/03/2022 Adjusted towards trip 3130」
0 => 「PAID」
1 => 「80」
2 => 「25/03/2022」
3 => 「Adjusted」
3 => 「towards」
3 => 「trip」
4 => 「3130」
「14 PAID 50 26/03/2022 Given to Nate Cash (padma ac) 3180」
0 => 「14 PAID」
1 => 「50」
2 => 「26/03/2022」
3 => 「Given」
3 => 「to」
3 => 「Nate」
3 => 「Cash」
3 => 「(padma」
3 => 「ac)」
4 => 「3180」
최종 답변 - Raku .subst( /…/, {…} )
또는 Raku의 s///
대체 명령/숙어를 사용하십시오. 참고: 두 대체 관용구 모두 대체 시 중괄호 안에 "호출 가능" 코드를 배치하여 각 명령의 기능을 크게 향상시킵니다. 따라서 .trans
나머지 공백 문자를 -
하이픈에 추가한 다음 join
세미콜론 에 추가할 수 있습니다 ;
.
~$ raku -ne '.subst(/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $/, \
{join ";", $0.trans(" " => "-"), $1, $2, $3.trans(" " => "-") // "", $4}).put;' file
#OR:
~$ raku -pe 's/ ^ (\d* \s? <.alpha>+) \s (\d+) \s ( \d**2 \/ \d**2 \/ \d**4 ) \s [(<.graph>+)+ % " " \s]? (\d+) $ \
/{join ";", $0.trans(" " => "-"), $1, $2, $3.trans(" " => "-") // "", $4}/;' file
출력 예(위 솔루션 중 하나):
Paid;100;15/02/2022;;3000
recd;50;15/02/2022;nelur-trip;3050
PAID;80;25/03/2022;Adjusted-towards-trip;3130
14-PAID;50;26/03/2022;Given-to-Nate-Cash-(padma-ac);3180
보너스 포인트: 예표준화{$0.uc}
첫 번째 열을 모두 등으로 변환하는 것과 PAID
같은 RECD
것을 사용하는 경우
가정 단순화: 정규식을 단순화하여 \d
숫자와 \D
숫자가 아닌 항목을 처리할 수 있지만 영국 우편번호나 항공사 확인 코드(특히 열 4 중간)와 같이 숫자/숫자가 아닌 "단어"가 혼합된 행을 구문 분석하지 못할 수도 있습니다. ).
https://docs.raku.org/routine/subst#Callable
https://docs.raku.org/언어/regexes
https://raku.org