마지막 필드를 이전 필드로 바꾸기

마지막 필드를 이전 필드로 바꾸기

다음과 같은 파일이 있습니다.

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

이렇게 하면 네 번째 필드가 임시 변수에 저장되고 네 번째 필드가 이전에 저장된 값으로 대체되며 새 줄이 인쇄됩니다. 인쇄 후 다음 반복을 위해 네 번째 필드의 이전 값을 저장합니다. 첫 번째 줄에서 "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 답변은 약간 길지만 행당 열 수가 하드 코딩되지 않았기 때문에 일반적인 솔루션에 더 가깝습니다. max파일 범위를 계산하세요.

짧게(두 가지 예) 두 가지 모두 쉼표 로 구분하여 lines읽고 배열에 저장합니다. 많은 (열)을 세어 저장합니다 . 그런 다음 Raku의 "Zip Reduction" 연산자를 사용하여 뒤따르는 두 목록에서 요소를 하나씩 가져옵니다. 요소는 정렬 및 재조립되어 이제 빈 문자열이 첫 번째 목록을 차지합니다. 행 끝에서, 후속 인덱스 값은 한 행 아래로 이동됩니다.split,@amaxelems$m[Z]flatjoinput""@a[$m-1]알아채다:Raku는 배열 요소를 자동으로 평면화하지 않으므로 flat필요한 경우 수동으로 10개로 평면화해야 합니다.

이 두 가지 예에서 저는 Raku의 "슈퍼" 연산자가 단일 요소에 대해 핑 기능/인덱스를 수행하거나 (메서드 체인의 끝에서) 콜론 형식을 사용하는 것과 >>어떻게 유사한지 보여주려고 합니다 . 괄호 개수가 필요합니다.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의 확장 정규식 모드를 사용하여 우리의 접근 방식은 언제든지 패턴 공간에서 두 줄을 유지하는 것입니다. 그런 다음 마지막에서 두 번째 필드를 이전 행에서 현재 행의 끝으로 이동합니다.

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

관련 정보