最初から最後まで、順番に入力を受け入れるか、または出力を反転するようにこの "printf"コードを変更するにはどうすればよいですか?

最初から最後まで、順番に入力を受け入れるか、または出力を反転するようにこの "printf"コードを変更するにはどうすればよいですか?

たとえば、次のコードは次のことができます。

[anony@mous-pc ~]$ (printf 'g?%s?m0\n' 008 006 004 002 ; printf 'wq\n') | ed -s file.txt

...内のすべての数字を選択してください...

[anony@mous-pc ~]$ cat file.txt
005
003
110
069
002
008
004
245
009
007
006

...希望の数字(または他の文字列)を一番上に移動します。しかし逆にコードが実行されました...

[anony@mous-pc ~]$ cat file.txt
002
004
006
008
005
003
110
069
245
009
007

...逆順を指定する限り、順序は最初から最後まで(逆順)になります。または…他の人はこれを上から下の形式と呼ぶことができます。もう一度、最初から最後まで実装します。このように最後のコマンドを実行する必要があります...

[anony@mous-pc ~]$ (printf 'g?%s?m0\n' 008 006 004 002 ; printf 'wq\n') | ed -s file.txt

しかし、最初から最後まで数字(または文字列)を入力して最初から最後まで順序を維持するにはどうすればよいですか?

入力結果を変更できない場合は、sed出力結果を変更して保存する前に反転または反転できますかfile.txt

答え1

$ perl -lne '
   /00[2468]$/ ? $h{$_} : $A[@A] = $_; }{
   print for @h{qw/008 006 004 002/}, @A;
' file.txt

一致する行と一致しない行を別のコンテナに保存します。印刷するときは、ハッシュ%h型の匿名配列から順序を抽出してください。

説明する:

  • 各行を読み、一致する行、つまり2、4、6、または8で終わる行が含まれていることを確認します。%h一致する行全体がキーになるようにハッシュに保存します$h{$_}
  • OTW、一致するものがない場合は、一致しない行を配列の後ろにプッシュします@A
  • ファイルの終わりを見た後、%hまずハッシュ値を印刷します。ご存知のように、ハッシュ値へのアクセスは本質的にランダムです。しかし、これがあなたのニーズの一つであるので、私たちは命令を出すべきです。そのため、表示したい順番でキーを一覧表示して順番を付けます。qw/008 006 004 002/これは匿名配列です。$h{008}これで印刷されます$h{006}
  • 次に、array @A一致しない行を含むコンテンツを印刷します。量子電気力学
  • 配列を印刷する順序を変更すると、一致する要素が北ではなく南に移動する@Aのがhash slice @h{...}わかります。
  • このコードはstdoutでのみ印刷されるため、元のコンテンツに戻す必要があります。perl '...' file.txt > /tmp/file.txt; mv /tmp/file.txt file.txt

答え2

移動したい順に、区切り線の後ろから移動したい行を移動し、区切り線の後ろのすべての行を文書の先頭に移動します。

まず、編集バッファの末尾に空白行を挿入し、次のように表示しますka

a

.
ka

バッファの最後の行を使用するのではなく、新しい行を区切り文字として挿入すると、最後の行が移動する必要がある行の1つである場合の複雑さを回避できます。空白行を移動するには、この特殊な区切り線に一意のテキストを挿入します---divider---

次に、一致する各行を表示したい行の上からリストしたい順にバッファの最後に移動します。

1,'a- g/008/ m$
1,'a- g/006/ m$
1,'a- g/004/ m$
1,'a- g/002/ m$

行を逆順に取得するには、バッファの終わりではなく表示された行の後に各行を挿入します。'a上記のコマンドの最後に、atの代わりに$この操作を実行できます。m

表示された行の後のすべての行をバッファの先頭に移動し、挿入された区切り線を削除して終了します。

'a+,$ m0
$ d

'a ddeleteで行を表示するのは短いですが、独自の文書化されていますが、$ d最後の行が削除される正しい行である理由を理解する必要があります。区切り線がバッファリングされるため、末尾を使用することもできます。'a,$ m01 d

ed -sviaに必要なコマンドを入力しますprintf(最後の2つのコマンドはバッファの行番号を印刷し、無条件にエディタを終了します)。

{
    printf '%s\n' a '' . ka
    printf "1,'a- g/%s/ m$\n" 008 006 004 002
    printf '%s\n' "'a+,$ m0" '$ d'
    printf '%s\n' ,n Q
} | ed -s file.txt

上記の解決策は、本質的にPerlが提案した解決策と同じです。別の答えとして、編集バッファの末尾にある行は配列として機能します@A

関連情報