将匹配行中的单词与另一行交换(后两行)

将匹配行中的单词与另一行交换(后两行)

我读了很多接近的问题,但没有找到解决我的问题的方法。

我有一个具有当前结构的文本文件:

## 誰 <!--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

相关内容