我有一个文件,fr.fc
代表使用的抽认卡硬盘我想用它来生成sed
类似的文件,fr-swapped.fc
%% This is a card set for hardv(1)
%% Created at Feb 1, 1997
NEXT 2023-09-10 09:18:28 +0200
PREV 2023-09-08 09:18:28 +0200
Q We should save money.
A Nous devons économiser de l'argent.
%%
NEXT 2023-09-09 10:51:14 +0200
PREV 2023-09-05 10:51:14 +0200
Q I should save money.
A Je dois économiser de l'argent.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Demander son chemin in four ways de quatre manières.
A Pardon, pouvez-vous m'aider ...
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q I need your help.
A Je besoin de votre aide.
%%
%%
我想将问题(以 开头^Q\t
)与答案(以 开头^A\t
)交换,而不交换Q
它们A
本身,以便结果看起来像这样。为了简单起见,我们假设答案和问题都只有一行长度。NEXT
和之后PREV
也是选项卡。答案或问题中间的任何分隔符都是空格 - 此处不允许使用表格。
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Je besoin de votre aide.
A I need your help.
%%
%%
我尝试过sed -n -E '/^Q\t/p; /^A\t/p' fr.fc | sed -E 'N; s/^([QA]{1,1})(.*)\n(.*)/\3\n\2/' >fr-swapped.fc
但没有成功。
答案1
惰性方法将在 slurp 模式下使用perl
,其中加载整个输入$_
,您可以对其进行替换:
perl -0777 -pe 's/^Q(\t.*\n)A(\t.*\n)/Q$2A$1/mg' your-file
如果像您问题的早期版本一样,Q
s 和A
s 可以由使用 TAB 缩进行继续的几行组成,那么很容易适应:
perl -0777 -pe 's/^Q(\t.*\n(?:\t.*\n)*)A(\t.*\n(?:\t.*\n)*)/Q$2A$1/mg' your-file
顺便说一句,应该是We should
-> Nous devrions
、I should
-> Je devrais
、I need
-> J'ai besoin de
。
答案2
为什么这么复杂?您可以将N;P;D
模式与 any 一起使用sed
,以始终同时处理两行,如下所示:
sed -E 'N;s/^Q(.*)(\nA)(.*)/Q\3\2A\1/;P;D'
它完全按照您的描述进行操作:将双线分成 Q 之后的所有内容和 A 之后的所有内容,然后交换这些部分。
答案3
使用GNUsed
$ sed -Ez 's/(Q[ \t]+)([^\n]*\n?)(A[ \t]+)([^\n]*\n?)/\1\4\3\2/gwfr-swapped.fc' fr.fc
$ cat fr-swapped.fc
%% This is a card set for hardv(1)
%% Created at Feb 1, 1997
NEXT 2023-09-10 09:18:28 +0200
PREV 2023-09-08 09:18:28 +0200
Q Nous devons économiser de l'argent.
A We should save money.
%%
NEXT 2023-09-09 10:51:14 +0200
PREV 2023-09-05 10:51:14 +0200
Q Je dois économiser de l'argent.
A I should save money.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Pardon, pouvez-vous m'aider ...
A Demander son chemin in four ways de quatre manières.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Je besoin de votre aide.
A I need your help.
%%
%%
答案4
这可能是您想要使用任何 awk 执行的操作:
$ cat tst.sh
#!/usr/bin/env bash
awk '
sub(/^Q\t/,"A\t") {
question = $0
next
}
sub(/^A\t/,"Q\t") {
$0 = $0 ORS question
}
{ print }
' fr.fc
$ ./tst.sh
%% This is a card set for hardv(1)
%% Created at Feb 1, 1997
NEXT 2023-09-10 09:18:28 +0200
PREV 2023-09-08 09:18:28 +0200
Q Nous devons économiser de l'argent.
A We should save money.
%%
NEXT 2023-09-09 10:51:14 +0200
PREV 2023-09-05 10:51:14 +0200
Q Je dois économiser de l'argent.
A I should save money.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Pardon, pouvez-vous m'aider ...
A Demander son chemin in four ways de quatre manières.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Je besoin de votre aide.
A I need your help.
%%
%%
如果您更看重清晰性,那么上面的内容就像 sed 一样简洁:
$ awk 'sub(/^Q\t/,"A\t"){q=$0;next}sub(/^A\t/,"Q\t"){$0=$0ORS q}1' fr.fc
%% This is a card set for hardv(1)
%% Created at Feb 1, 1997
NEXT 2023-09-10 09:18:28 +0200
PREV 2023-09-08 09:18:28 +0200
Q Nous devons économiser de l'argent.
A We should save money.
%%
NEXT 2023-09-09 10:51:14 +0200
PREV 2023-09-05 10:51:14 +0200
Q Je dois économiser de l'argent.
A I should save money.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Pardon, pouvez-vous m'aider ...
A Demander son chemin in four ways de quatre manières.
%%
%%
NEXT 2023-09-08 20:50:03 +0200
PREV 2023-09-08 20:50:03 +0200
Q Je besoin de votre aide.
A I need your help.
%%
%%
根据上面评论中我的问题的答案,可能会有更好的解决方案。