가까운 질문을 많이 읽었지만 문제에 대한 해결책을 찾지 못했습니다.
현재 구조의 텍스트 파일이 있습니다.
## 誰 <!--QR2Y;1;2023-04-18-->
だれ
quelqu'un, qui, quel
田中さんてだれですか。
« Qui est ce M. Tanaka ? »
## 歌う <!--T2B7;1;2023-04-18-->
うたう
chanter, réciter
ピアノに合わせて歌う。
« Chanter accompagné d'un piano. »
목적은 정보를 교환하고 재정렬하는 것입니다.
- 로 시작하는 줄에서 일본어 단어를 가져와
##
다음 두 줄로 바꿉니다. - 이 줄을 삭제한 후 두 줄
- 이 일본어 단어를 수정된
##
줄 아래에 넣으세요.
이런 결과를 얻으려면
## quelqu'un, qui, quel <!--QR2Y;1;2023-04-18-->
誰
だれ
田中さんてだれですか。
« Qui est ce M. Tanaka ? »
## chanter, réciter <!--T2B7;1;2023-04-18-->
歌う
うたう
ピアノに合わせて歌う。
« Chanter accompagné d'un piano. »
구조는 항상 똑같습니다. 가변부분은 <!--X0X0;0;000-00-00-->
항상 변하는 부분이고 때로는 전혀 존재하지 않는 부분이다.
이것은 sed
해결책인 것 같지만 문서에서 약간 길을 잃었습니다...
답변1
솔루션awk
- 동일한 문서를 사용하여
awk
두 번 급지 - 첫 번째 실행 시:
##
발견 되면jw
(일본어 단어)와 해당 단어fw
(프랑스어 단어)를 배열로 저장하고, 행 번호(NR
)로 색인을 지정합니다.
- 두 번째 실행에서는 다음을 수행합니다.
- 줄 번호가 있는지 확인한
fw
후 일본어 단어를 프랑스어 단어로 바꾸고 해당 일본어 단어를 인쇄합니다. - 방금 배치한 프랑스어 단어가 있는 줄을 제외한 모든 줄을 인쇄합니다.
- 줄 번호가 있는지 확인한
awk '
NR == FNR && /^##/ { jw[NR]=$2; nr=NR; }
NR == nr+2 {fw[NR-2]=$0}
NR>FNR {
if(FNR in fw) { $2 = fw[FNR]; print; print jw[FNR]; }
else { if (!(FNR-2 in fw)) print; }}
' file file
산출:
## quelqu'un, qui, quel <!--QR2Y;1;2023-04-18-->
誰
だれ
田中さんてだれですか。
« Qui est ce M. Tanaka ? »
## chanter, réciter <!--T2B7;1;2023-04-18-->
歌う
うたう
ピアノに合わせて歌う。
« Chanter accompagné d'un piano. »
답변2
원패스 솔루션은 다음과 같습니다.
awk '/^##/ {hdr=$0; j1=$2; getline; j2=$0; getline; fr=$0;
sub(/## [^<]+/, "## " fr " ", hdr); print hdr; print j1; print j2; next } 1' input
- 그러면 시작 패턴으로 헤더 행이 식별되어
##
변수에 저장됩니다hdr
. j1
그런 다음 첫 번째 일본어 부분을 줄의 두 번째 공백으로 구분된 필드로 추출합니다 (공백이 포함되어 있지 않다고 가정합니다).- 다음 줄을 읽고 두 번째 일본어 부분에 완전히 버퍼링합니다
j2
. - 다음 줄을 다시 읽고 프랑스어 번역으로 버퍼링합니다
fr
. - 그런 다음 버퍼링된 헤더의 첫 번째 일본어 부분을 프랑스어 번역으로 대체하여 수정된 헤더와 두 개의 일본어 부분을 각각 한 줄에 인쇄합니다. 그런 다음 다음 실행 줄로 점프합니다.
1
다른 모든 줄은 규칙 블록 외부에 있기 때문에 수정 없이 인쇄됩니다(외견상 길을 잃은 것처럼 보임).
답변3
1패스로 멀티바이트 문자를 지원하는 awk를 사용하세요(일본어 단어의 경우).
awk '
BEGIN { RS=""; ORS="\n\n"; FS=OFS="\n" }
/^##/ { split($1,a," "); $1=a[1] " " $3 " " a[3]; $3=$2; $2=a[2] }
1' file
## quelqu'un, qui, quel <!--QR2Y;1;2023-04-18-->
誰
だれ
田中さんてだれですか。
« Qui est ce M. Tanaka ? »
## chanter, réciter <!--T2B7;1;2023-04-18-->
歌う
うたう
ピアノに合わせて歌う。
« Chanter accompagné d'un piano. »
레코드 사이에 빈 줄이 없어 RS=""
작동하지 않으면 다음과 같이 할 수 있습니다(여전히 1패스, ##
각 청크에 대해 3줄 버퍼링).
$ cat tst.awk
BEGIN { FS=OFS="\n" }
/^##/ { lineNr=1; buf = $0; next }
lineNr { lineNr++; buf = buf RS $0 }
lineNr == 3 {
$0 = buf
split($1,a," "); $1=a[1] " " $3 " " a[3]; $3=$2; $2=a[2]
lineNr = 0
}
!lineNr
$ awk -f tst.awk file
## quelqu'un, qui, quel <!--QR2Y;1;2023-04-18-->
誰
だれ
田中さんてだれですか。
« Qui est ce M. Tanaka ? »
## chanter, réciter <!--T2B7;1;2023-04-18-->
歌う
うたう
ピアノに合わせて歌う。
« Chanter accompagné d'un piano. »
답변4
그리고 perl
:
perl -00pe 's/^(##\s*)(.*?)(\s*<!--.*-->\n)(.*)\n(.*)/$1$5$3$2\n$4/' your-file