最初の文字以外の行の残りの部分をsedに変更するにはどうすればよいですか?

最初の文字以外の行の残りの部分をsedに変更するにはどうすればよいですか?

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結果を次のようにしたいと思います。簡単にするために、答えと質問の両方が1行の長さであるとしましょう。その後もタブがあります。答えや質問の間の区切り文字は空白です。ここではテーブルは使用できません。QANEXTPREV

%%
%%
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

perl怠惰なメソッドは、入力全体がロードされ、$_それを置き換えることができるslurpモードで使用されます。

perl -0777 -pe 's/^Q(\t.*\n)A(\t.*\n)/Q$2A$1/mg' your-file

以前のバージョンの質問のように、QsとAsがTABインデントを使用して連続する複数行で構成できる場合は、簡単に適応できます。

perl -0777 -pe 's/^Q(\t.*\n(?:\t.*\n)*)A(\t.*\n(?:\t.*\n)*)/Q$2A$1/mg' your-file

ところでWe should-> Nous devrionsI should-> Je devraisI need->でなければなりませんJ'ai besoin de

答え2

なぜそんなに複雑なのですか?次のようにN;P;Dパターンをanyとともに使用するsedと、常に2行を同時に処理できます。

sed -E 'N;s/^Q(.*)(\nA)(.*)/Q\3\2A\1/;P;D'

それはあなたが説明するものとまったく一致しています。二重線をQの後ろのすべてとAの後ろのすべてに分割し、その部分を交換します。

答え3

GNUの使用sed

$ 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.
%%
%%

上記のコメントの私の質問に答えると、より良い解決策があるかもしれません。

関連情報