n번째 행 삭제(맨 아래부터)

n번째 행 삭제(맨 아래부터)

파일의 줄 수를 알 수 없습니다. Unix 플랫폼에서 한 줄의 명령(필요한 경우 여러 줄 사용)으로 n번째 줄(아래에서 위로 계산)을 삭제하는 방법입니다.

답변1

예를 들어, 맨 아래에서 네 번째 행을 삭제하려면 다음 명령을 사용하십시오 sed.

tac input | sed '4d' | tac

입력 파일을 덮어쓰려면:

tmpfile=$(mktemp)
tac input | sed '4d' | tac > "$tmpfile" && mv "$tmpfile" input

답변2

순수한 sed:

  • 만약에N그것은 1입니다:

    sed '$ d'
    

    간단합니다. 마지막 줄인 경우 패턴 공간을 제거하면 인쇄되지 않습니다.

  • 만약에N1보다 큼( 로 사용 가능 $n):

    sed "
       : start
       1,$((n-1)) { N; b start }
       $ { t end; s/^//; D }
       N
       P
       D
       : end
     "
    

    시작하기 $((n-1))전에 쉘에 의해 확장된다는 점에 유의하십시오 sed.

    이 조각

    : start
    1,$((n-1)) { N; b start }
    

    가게N- 패턴 공간에 1줄. 이 루프에서 입력 스트림의 끝에 도달 하면 sed패턴 공간이 자동으로 인쇄됩니다(끝에서 n번째 줄도 삭제되지 않습니다).

    더 많은 입력을 가정합니다. 그런 다음 마지막 행에 도달하기 전에 다음 조각을 반복합니다.

    N   # read the next line of input and append it to the pattern space
    P   # print the first line from the pattern space
    D   # delete the first line from the pattern space and start a new cycle
    

    이러한 방식으로 패턴 공간은 입력을 기반으로 몇 줄씩 출력을 "지연"하는 버퍼입니다. N입력의 마지막 줄도 이 조각에서 읽을 수 있습니다.

    마지막 줄을 읽은 후 다음이 실행됩니다.

    $ { t end; s/^//; D }
    

    이 코드가 처음 실행되면 이전에 성공한 대체가 없었기 때문에 t분기되지 않습니다 . 그런 다음 이 no-op 대체가 수행되고 패턴 공간의 첫 번째 줄은 인쇄되지 않고 삭제( )됩니다. 이것이 바로 삭제하려는 행입니다. 새로운 루프가 시작 되므로 동일한 코드 줄이 결국 다시 실행됩니다. 이번에 는 으로 분기됩니다 .ends/^//DDtend

    sed스크립트 끝에 도달 하면 패턴 공간이 자동으로 인쇄됩니다. 나머지 모든 줄이 인쇄됩니다.

    이 명령은 n=2(유효) 및 (유효하지 않음)에 대해 n=1동일한 출력을 생성 합니다. 상황에 관계없이 작동하는 단일 솔루션을 찾으려고 노력 중입니다.N. 나는 실패했으므로 특별한 경우에는N1입니다.

답변3

$n삭제하려는 행 수를 유지하는 경우

다음을 사용하여 한 줄 삭제

printf "\$-%d+1,\$-%d+1d\nwq\n" $n $n| ed -s file

마지막 n줄 삭제

printf "\$-%d,\$d\nwq\n" $n | ed -s file

어디

  • \$%d,\$ded에게 마지막 n 줄을 삭제하라고 지시합니다(printf는 n을 삽입합니다)
  • wq작성을 마치고 종료합니다.
  • -s의지 ed -s침묵 에드.

  • 삭제할 행이 충분한지 확인할 수 있는 조항이 없습니다.

아쉽게도 범위는끝에서sed...에서 지정할 수 없습니다 .

답변4

head을 결합 하여 tail이를 달성 할 수 있습니다 .

만약에n번째맨 아래 행을 삭제해야 합니다.

  1. head표준 입력에서 읽고 표준 출력에 보고합니다.총-n위에서부터 시작하는 줄
  2. tail하단의 표준 출력을 읽고 보고합니다.n-1표준 입력의 라인.
  3. 전체적으로 행은 순서대로 표준 출력에 보고되며 끝에서 시작하는 *n번째 행은 건너뜁니다.

이 해결 방법은 head마지막으로 보고된 줄 이후 열린 파일 설명의 파일 오프셋을 유지하는 것에 달려 있습니다. head표준 입력이 파일에서 리디렉션될 때 GNU가 이 작업을 수행한다고 생각합니다.

n=200; tmpfile=$(mktemp) && { head -n -$n; tail -n -$((n-1)); }<file >"$tmpfile" \
    && mv -- "$tmpfile" file

관련 정보