[unix] 임시 파일을 사용하지 않고 출력의 첫 N 줄을 끝으로 이동

다음과 같은 명령의 출력을 상상해보십시오.

44444
55555
11111
22222
33333

첫 번째 N 줄을 잡아 당기고 (위 예제에서 처음 두 줄) 끝에 임시 파일을 추가 하지 않고 어떻게 추가 할 수 있습니까 (파이프 만 사용)?

11111
22222
33333
44444
55555

라인을 따라 뭔가 | sed -n '3,5p;1,2p'(sed로 분명히 작동하지 않는 것은 명령의 순서에 신경 쓰지 않습니다).



답변

해당 행을 보류 버퍼에 복사 한 다음 삭제하고 마지막 행에서 보류 버퍼의 내용을 패턴 공간에 추가하십시오.

some command | sed '1,NUMBER{           # in this range
H                                       # append line to hold space and
1h                                      # overwrite if it's the 1st line
d                                       # then delete the line
}
$G'                                     # on last line append hold buffer content

으로 gnu sed당신이로 쓸 수

some command | sed '1,NUMBER{H;1h;d;};$G'

여기 올과 다른 방법 ed(그것 r의 출력 EADS some command텍스트 버퍼를 다음 m라인 oves 1,NUMBER라 후 $t 하나)

ed -s <<IN
r ! some command
1,NUMBERm$
,p
q
IN

지적했듯이 출력에 NUMBER+1 줄 미만이면 둘 다 실패합니다 . 더 확실한 접근법은 다음과 같습니다 ( gnu sed구문).

some command | sed '1,NUMBER{H;1h;$!d;${g;q;};};$G'

이 줄은 마지막 줄 ( $!d) 이 아닌 한 해당 범위의 줄만 삭제합니다. 그렇지 않으면 보류 버퍼 내용 ( g)으로 패턴 공간을 덮어 쓴 다음 q현재 패턴 공간을 인쇄 한 후 uits를 덮어 씁니다 .


답변

awk방법 :

cmd | awk -v n=3 '
  NR <= n {head = head $0 "\n"; next}
  {print}
  END {printf "%s", head}'

@don_crissti의 sed접근 방식에 대한 한 가지 이점 은 출력에 줄이 없거나 적을 경우 여전히 작동한다는 것입니다 (줄을 출력합니다) n.


답변

나는 이것을 가지고 xclip이렇게 할 수 있습니다 :

./a_command | xclip -in && xclip -o | tail -n +3 && xclip -o | head -n 2

설명은 다음과 같습니다.

xclip - command line interface to X selections (clipboard)

NAME
       xclip - command line interface to X selections (clipboard)

SYNOPSIS
       xclip [OPTION] [FILE]...

DESCRIPTION
       Reads from standard in, or from one or more files, and makes the data available as an X selection for pasting into X applications. Prints current X selection to standard out.

       -i, -in
              read text into X selection from standard input or files (default)

       -o, -out
              prints the selection to standard out (generally for piping to a file or program)


답변

펄 방식 :

perl -ne '$.<3?($f.=$_):print;}{print $f'

또는 덜 암호 적으로 작성된 동일한 내용 :

perl -ne 'if($.<3){ $f.=$_ } else{ print } END{print $f}'

예를 들면 다음과 같습니다.

$ cat file
44444
55555
11111
22222
33333

$ cat file | perl -ne '$.<3?($f.=$_):print;}{print $f'
11111
22222
33333
44444
55555

설명

  • -ne: 입력 파일 / 스트림을 한 줄씩 읽고 -e각 줄에 지정된 스크립트를 적용하십시오 .
  • $.<3: $.는 현재 행 번호이므로 3이동하려는 행 수로 변경 하십시오.
  • $.<3?($f.=$_):print;:이 조건 연산자는 일반적인 형식은,이다 condition ? case1 : case2, 그것은 실행 case1하면 condition참이고 case2거짓 일 경우. 여기서 현재 줄 번호가 3보다 작 으면 현재 줄 ( $_)을 변수에 추가 $f하고 줄 번호가 3보다 크면 인쇄합니다.
  • }{ print $f: }{는 perl 속기입니다 END{}. 모든 입력 라인이 처리 된 후에 실행됩니다. 이 시점에서 우리는 이동하려는 모든 줄을 모으고 남겨두고 싶은 모든 줄을 인쇄 할 것 $f입니다.

답변

POSIX를 사용하십시오 ex. 예, 파일 편집 용이지만 파이프 라인에서 작동합니다.

printf %s\\n 111 222 333 444 555 | ex -sc '1,2m$|%p|q!' /dev/stdin

파이프 라인의 시작 또는 끝에 임의의 명령을 추가 할 수 있으며 동일하게 작동합니다. 더 나은 /dev/stdin점은 POSIX를 준수한다는 점입니다.

( /dev/stdinPOSIX에 지정되어 있는지 여부 는 알 수 없지만 Linux와 Mac OS X에 모두 표시되어 있습니다.)

이것은 sed홀드 스페이스 를 사용하는 것보다 가독성이 뛰어 ex납니다. “이 라인을 끝까지 이동하십시오” 라고 말하면 됩니다. (나머지 명령은 “버퍼 인쇄”및 “종료”를 의미하며, 읽기도 가능합니다.)

NB : ex입력으로 2 줄 미만을 제공하면 위에 제공된 명령이 실패합니다.

더 읽을 거리 :


답변

짧은 python스 니펫 :

#!/usr/bin/env python3
import sys
file_ = sys.argv[1]
lines = int(sys.argv[2])
with open(file_) as f:
    f = f.readlines()
    out = f[lines:] + f[:lines]
    print(''.join(out), end='')

파일 이름을 첫 번째 인수로 전달하고 줄 수를 두 번째 인수로 전달하십시오.

예:

$ cat input.txt
44444
55555
11111
22222
33333

$ ./sw_lines.py input.txt 2
11111
22222
33333
44444
55555

$ ./sw_lines.py input.txt 4
33333
44444
55555
11111
22222


답변

전체 출력을 메모리에 저장할 수있는 경우 :

data=$(some command)
n=42                  # or whatever
{ tail -n +$((n+1)) <<<"$data"; head -n $n <<<"$data"; } > outputfile