파일의 줄 수를 알 수 없습니다. 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 대체가 수행되고 패턴 공간의 첫 번째 줄은 인쇄되지 않고 삭제( )됩니다. 이것이 바로 삭제하려는 행입니다. 새로운 루프가 시작 되므로 동일한 코드 줄이 결국 다시 실행됩니다. 이번에 는 으로 분기됩니다 .end
s/^//
D
D
t
end
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,\$d
ed에게 마지막 n 줄을 삭제하라고 지시합니다(printf는 n을 삽입합니다)wq
작성을 마치고 종료합니다.-s
의지ed -s
침묵 에드.삭제할 행이 충분한지 확인할 수 있는 조항이 없습니다.
아쉽게도 범위는끝에서sed
...에서 지정할 수 없습니다 .
답변4
head
을 결합 하여 tail
이를 달성 할 수 있습니다 .
만약에n번째맨 아래 행을 삭제해야 합니다.
head
표준 입력에서 읽고 표준 출력에 보고합니다.총-n위에서부터 시작하는 줄tail
하단의 표준 출력을 읽고 보고합니다.n-1표준 입력의 라인.- 전체적으로 행은 순서대로 표준 출력에 보고되며 끝에서 시작하는 *n번째 행은 건너뜁니다.
이 해결 방법은 head
마지막으로 보고된 줄 이후 열린 파일 설명의 파일 오프셋을 유지하는 것에 달려 있습니다. head
표준 입력이 파일에서 리디렉션될 때 GNU가 이 작업을 수행한다고 생각합니다.
n=200; tmpfile=$(mktemp) && { head -n -$n; tail -n -$((n-1)); }<file >"$tmpfile" \
&& mv -- "$tmpfile" file