最後のフィールドを前のフィールドに置き換える

最後のフィールドを前のフィールドに置き換える

次のファイルがあります。

10-04-2022 00:39:13,36707,1455008753,32
11-05-2022 00:39:13,36708,1555008753,26
21-05-2022 00:39:13,36708,1555408753,15
12-06-2022 00:39:13,36709,1655008753

最後のフィールドの値は次の行のランタイムに関連しているので、gnuplotで使用するためにこの方法で下に移動したいと思います。

10-04-2022 00:39:13,36707,1455008753,
11-05-2022 00:39:13,36708,1555008753,32
21-05-2022 00:39:13,36708,1555408753,26
12-06-2022 00:39:13,36709,1655008753,15

答え1

単純な awk スクリプトで次のことができます。

awk 'BEGIN {FS=OFS=","} { tmp=$NF; $NF=save; print; save=tmp; }' < input > output

これにより、4番目のフィールドが一時変数に保存され、4番目のフィールドが以前に保存された値に置き換えられ、新しい行が印刷されます。印刷後、次の反復のために4番目のフィールドの前の値を保存します。最初の行では、「save」d値は空で(デフォルトのawk動作)、期待される結果が得られます。

「BEGIN」セクションは、フィールド区切り文字(入力を分割するために使用されます)と出力フィールド区切り文字(行/フィールドを印刷するときに使用されます)をコンマに設定します。ローカルawkのマニュアルページ、さまざまなオンラインリファレンスを参照してください。awkのオープングループ基本仕様もっと学ぶ。

答え2

GNU 5.1.0でテストされた別のawkソリューションです。awk

$ awk -F, -v OFS=, '{print $1,$2,$3,x;x=$NF}' myfile
10-04-2022 00:39:13,36707,1455008753,
11-05-2022 00:39:13,36708,1555008753,32
21-05-2022 00:39:13,36708,1555408753,26
12-06-2022 00:39:13,36709,1655008753,15
$

答え3

使用幸せ(以前のPerl_6)

raku -e 'my @a = lines>>.split(","); my $m = @a>>.elems.max;  \
         .flat.join(",").put for [Z] @a>>.[0..$m-2], ("", @a>>.[$m-1]).flat;'

または

raku -e 'my @a = lines.map: *.split(","); my $m = @a.map(*.elems).max;  \
         .flat.join(",").put for [Z] @a.map(*.[0..$m-2]), ("", @a.map: *.[$m-1]).flat;' 

このRakuの回答は少し長いですが、1行あたりの列数がハードコードされていないため、一般的な解決策に近いです。maxファイルの範囲を計算します。

短く(両方の例)、両方をコンマで区切って読み、lines配列に保存します。多くの(列)を数えて保存します。次に、Rakuの「Zip Reduction」演算子を使用して、次の2つのリストから要素を1つずつ取得します。要素が並べ替えられ、再組み立てられ、空の文字列が最初のリストを占めるようになりました。行の終わりに、後続のインデックス値は1行下に移動されます。split,@amaxelems$m[Z]flatjoinput""@a[$m-1]気づく:Rakuは配列要素を自動的に平面化しないため、flat必要に応じて手動で10個に平面化する必要があります。

この2つの例では、Rakuの「スーパー」演算子が単一の要素に対してping機能/インデックスを実行するか(メソッドチェーンの最後に)コロン形式を使用するのとどのように>>似ているかを示したいと思います。括弧の数が必要です。map.map(*.fn).map: *.fn;

入力例:

10-04-2022 00:39:13,36707,1455008753,32
11-05-2022 00:39:13,36708,1555008753,26
21-05-2022 00:39:13,36708,1555408753,15
12-06-2022 00:39:13,36709,1655008753

出力例:

10-04-2022 00:39:13,36707,1455008753,
11-05-2022 00:39:13,36708,1555008753,32
21-05-2022 00:39:13,36708,1555408753,26
12-06-2022 00:39:13,36709,1655008753,15

付録:別の Raku 方法があります。今回は、行/列を別の要素に展開し、 を使用して上記とrotor同じ結果を提供します。

raku -e 'my @a = lines>>.split(",").flat; my @b = @a[3,7,11...*];  \
         @a.=rotor(3 => 1); @a.=map(*.join(",")); @b.=unshift(""); \
        .join(",").put for [Z] @a, @b;' 

https://docs.raku.org/言語/operators#index-entry-[]_(reduction_metaoperators)
https://docs.raku.org/言語/operators#index-entry-hyper_method_call_operator
https://docs.raku.org/routine/Flat

答え4

正規表現の作成を簡素化するために、GNU sedの拡張正規表現モードを使用して、私たちのアプローチは、いつでもパターン空間に2行を維持することです。次に、最後から2番目のフィールドを前の行から現在の行の最後に移動します。

sed -E '
  1s/$/,/
  $!N
  s/(,[^,]+)(,[^,]*\n.*)/\2\1/
  P;D
' file

入力する:-

10-04-2022 00:39:13,36707,1455008753,32
11-05-2022 00:39:13,36708,1555008753,26
21-05-2022 00:39:13,36708,1555408753,15
12-06-2022 00:39:13,36709,1655008753#

出力:-

10-04-2022 00:39:13,36707,1455008753,
11-05-2022 00:39:13,36708,1555008753,32
21-05-2022 00:39:13,36708,1555408753,26
12-06-2022 00:39:13,36709,1655008753#,15

関連情報