쉘 명령을 사용하여 파일의 처음 n 줄과 마지막 줄을 어떻게 삭제합니까?


31

Element_query쿼리 결과를 포함 하는 파일 이 있습니다.

SQL> select count (*) from element;

[Output of the query which I want to keep in my file]

SQL> spool off;

shell 명령을 사용하여 첫 번째 줄과 마지막 줄을 삭제하고 싶습니다.


2
SQL * Plus에서이 문제를 해결하는 것이 가장 좋습니다. 파일을 생성 한 다음 원하지 않는 항목을 잘라내려고 시도하는 대신 SQL * Plus에 해당 항목을 생성하지 않도록 지시하면됩니다. 한 가지 방법은 docs.oracle.com/cd/A84870_01/doc/sqlplus.816/a75664/ch44.htm의 "플랫 파일 작성"섹션에 설명되어 있습니다 . 다른 접근법은 stackoverflow.com/q/2299375/978917에 설명되어 있습니다.
ruakh

답변:


48

GNU 사용 sed:

sed -i '1d;$d' Element_query

작동 방식 :

  • -i옵션 파일 자체를 편집하십시오. 해당 옵션을 제거하고 원하는 경우 출력을 새 파일 또는 다른 명령으로 리디렉션 할 수도 있습니다.
  • 1d첫 번째 줄을 삭제합니다 (첫 번째 줄 1에서만 작동, d삭제)
  • $d마지막 줄을 삭제합니다 (마지막 줄 $에 대해서만 작동 d하고 삭제)

더 나아 가기 :

  • 범위를 삭제할 수도 있습니다. 예를 들어 1,5d처음 5 줄을 삭제합니다.
  • SQL>명령문 을 사용하여 시작하는 모든 행을 삭제할 수도 있습니다 ./^SQL> /d
  • 당신은 모든 빈 줄을 삭제할 수 있습니다 /^$/d
  • 마지막으로, 명령문을 세미콜론 ( statement1;statement2;satement3;...)으로 분리하거나 명령 행 ( -e 'statement1' -e 'statement 2' ...) 에서 별도로 지정 하여 명령문을 결합 할 수 있습니다.

세 번째 줄을 삭제하려면 ... 1d 대신 3d를 사용해야합니까? 세 번째 줄이 마지막부터 삭제되면 ... 명령어는 무엇입니까?
pmaipmui

쉘 명령을 사용하여 마지막에서 세 번째 줄을 삭제하는 방법은 무엇입니까?
pmaipmui

@Nainita 범위를 지정할 수 1,3d있지만 (처음 세 줄은 삭제됨 ) 결국에는 조금 더 어려워집니다. 원하는 내용에 따라 다음을 사용하는 것이 좋습니다 . 파일의 위치에 관계없이 sed -i '/^SQL> /d' Element_query시작하는 행을 삭제 하는 것이 좋습니다 SQL> .
user43791 2016 년

@ Nainita- 임의의 테일 카운트에 대한 내 대답을 참조하십시오 - 파일 끝을 기준으로 카운트 라인 을 제거하는 두 가지 솔루션을 제공 합니다. 하나는 sed하나의 라이너 입니다. 파일 의 헤드 테일 에서 임의의 줄 수를 제거하는 데 효과적입니다. 입력이 일반 파일 인 한 두 개의 head프로세스 에서 단일 입력을 그룹화하는 것이 좋습니다. 가장 빠른 방법은 보통입니다.
mikeserv 2016 년

나는 sed -i '1d' table-backup.sqlSQL 텍스트 파일의 첫 줄을 삭제
David Thomas

8

머리; 머리

{   head -n[num] >/dev/null
    head -n[num]
}  <infile >outfile

위와 같이 첫 번째 head명령으로 출력 헤드에서 제거 할 첫 번째 줄 수와 두 번째 명령에 쓸 줄 수를 지정할 수 있습니다 outfile. 또한 일반적으로 두 번의 호출이 필요하지만 sed입력이 경우 보다 빠르게 수행합니다 . 어디 sed확실히 해야 하지만 선호, 경우에 <infile이다 없는 일반, lseekable 이 일반적으로 때문에 - 파일이 없는 경우 의도지만, 같은 작업 sed하나의 스크립트 과정에서 모든 출력 수정을 처리 할 수 있습니다.

GNU head를 사용 하면 두 번째 명령에서도 -부정적인 형식을 사용할 수 있습니다 [num]. 이 경우 다음 명령은 입력에서 첫 번째와 마지막 행을 제거합니다.

{   head -n1 >/dev/null
    head -n-1
}  <infile >outfile

또는 POSIX sed:

예를 들어, 20 줄의 입력을 읽었으며 처음 3과 마지막 7을 제거하고 싶다고 말하면 w /으로 해결 sed하면 꼬리 버퍼로 수행합니다. 먼저 총 스트립 수 10에 3과 7을 더한 다음 다음을 수행합니다.

seq 20 | sed -ne:n -e '3d;N;1,10bn' -eP\;D

입력에서 처음 3 줄과 마지막 7 줄을 제거하는 예제입니다. 아이디어는 스택의 패턴 공간에서 입력의 꼬리에서 제거하려는만큼 많은 행을 버퍼링 할 수 있지만 P가져온 모든 행에 대해 첫 번째 행만 제거한다는 것입니다.

  • 라인 1,10 sed P마다 b랜치 루프 에서 라인 단위로 패턴 공간에 입력을 쌓기 때문에 라인을 헹구지 않습니다 .
  • 세 번째 줄에는 모든 sed스택이 d제거되므로 첫 세 줄은 한 번의 출력으로 제거됩니다.
  • 경우 sed도달 $당길 입력 시도 마지막 행 N내선는 EOF 안타 완전히 처리를 중지. 그러나 그 시간 패턴 공간에 라인이 모두 포함 14,20-의 어느 것도 아직 한 Printed하지 않으며, 결코.
  • 다른 모든 라인 에서는 패턴 공간에서 sed P처음 발생하는 \newline까지만 헹구고 D남아있는 것 또는 다음 6 라인의 입력으로 새로운 사이클을 시작하기 전에 동일하게 엘레멘트를냅니다. N새 사이클에서 ext 명령을 사용하여 7 번째 줄이 스택에 다시 추가됩니다 .

그래서의 seq의 출력 (20 개 순차적으로 번호가 매겨진 라인 임) , sed단지 지문 :

4
5
6
7
8
9
10
11
12
13

입력의 테일에서 제거하고자하는 라인의 수가 클 때 문제가됩니다. 왜냐하면 sed성능은 패턴 공간의 크기에 정비례하기 때문입니다. 그럼에도 불구하고 많은 경우에 실행 가능한 솔루션입니다. POSIX는 sed버스 팅 전에 최소 4kb를 처리 할 패턴 공간을 지정합니다.


1
gnu tail는 또한 tail -n+<num>"start from line <num>"을 의미 하는 확장 된 구문을 지원합니다
UloPe

4

여러 줄을 삭제하는 방법에 대해서는 대답하지 않겠습니다. 이런 식으로 문제를 공격 할 것입니다.

grep -v '#SQL>' Element_query >outfile

행 수를 계산하는 대신 프롬프트를 인식하여 SQL 명령을 제거합니다. 이 솔루션은 두 개 이상의 명령으로 더 많은 SQL 세션의 다른 출력 파일에 대해 일반화 할 수 있습니다.


나는 그것을 좋아한다. SQL에 대해 잘 모르지만 출력 줄의 헤드에서 프롬프트가 발생할 가능성이 없습니까?
mikeserv 2016 년

4

ed은 '표준 텍스트 편집기'이며 GNU가없는 시스템에서 사용할 수 있어야합니다 sed. 원래 텍스트 편집기로 설계되었지만 스크립팅에 적합합니다.

printf '%s\n' 1d '$d' w q | ed Element_query

1d$d쉘이 변수라고 생각하지 않도록 인용 된 파일의 첫 번째 행을 삭제하고 마지막 행을 삭제 w하고 파일을 쓰고 q종료 ed합니다. printf여기서 명령의 형식을 지정하는 데 사용됩니다. ed각 명령 에는 개행 문자가 와야합니다. 물론 이것을 달성하는 다른 방법이 있습니다.


3

파일에서 선행 및 후행을 제거하는 방법에는 여러 가지가 있습니다.

awk패턴 매칭과 라인 카운팅을 모두 처리 할 수 있습니다 .

#you need to know length to skip last line, assume we have 100 lines
awk 'NR>1 && NR<100 {print $0};' < inputfile
#or
awk '/SQL/ {next}; {print $0;};' < inputfile |awk 'NR>1&& NR<10 {print $0};'

당신은 사용할 수 있습니다 grep -v당신이 패턴에 의해 원하지 않는 라인을 제외하고는 사용하여 여러 패턴을 일치시킬 수 있습니다 -E, 옵션을

grep -v -E "SQL>" < inputfile > outputfile

특정 줄 수를 사용 head하고 tail잘라낼 수 있습니다 .

lines=$((`wc -l < inputfile`-2)) #how many lines in file, less 2
head -n-1 < inputfile | head -n$lines > outputfile
#or
tail -n+2 < inputfile | head -n$lines > outputfile

을 사용 vi/vim하고 첫 번째와 마지막 줄을 삭제할 수 있습니다 .

vi inputfile
:1
dd
:$
dd
:w! outputfile
:x

펄 스크립트를 사용하고, 첫 줄을 건너 뛰고, 각 줄을 저장하고, 다음 줄을받을 때 인쇄 할 수 있습니다.

#left as exercise for the reader :-)

1
의 경우 head실제로 파이프가 필요하지 않으며 실제로 파이프를 피할 수 있으면 파이프를 전혀 사용하지 않는 것이 좋습니다. 당신이 할 때 head | head- 두 개의 프로세스가 동시에 실행할 수있는 동안, 그들은 또한 둘 다 거의 모든 중복 동일한 데이터의 처리입니다. 대신 { head >dump; head >save; } <in오프셋으로 만 건너 뜁니다. 첫 번째 줄은 10 줄을 >dump읽고 두 번째 줄 은 다음 10 줄을 읽습니다 >save.
mikeserv 2016 년

3

SQL 명령 을 잘라 내면 훨씬 더 나은 결과를 얻을 수 있습니다 . 두 가지 방법으로이 작업을 수행 할 수 있습니다.

  1. 당신이 경우 절대적으로 확신 순서가 "고 SQL>"않습니다 하지 출력에 다른 곳에서는 발생

    grep -v -F 'SQL> ' < infile > outfile
  2. 확실하지 않으면

    grep -v '^SQL> .*;$' < infile > outfile

두 번째 버전은 더 느리지 만 더 정확합니다. "SQL>"로 시작하고 세미콜론으로 끝나는 줄은 무시하고,이 줄은 제거하려는 줄을 나타냅니다.

그러나 파일에 추가 출력을 넣지 않는 것이 좋습니다. 대부분의 SQL 시스템에는 몇 가지 방법이 있습니다. 나는 오라클에 너무 익숙하지 않지만 이 답변 이 도움 될 수 있습니다.


3

범위 사이의 선을 선택할 수 있습니다 awk(여기서는 선 수를 알고 있다고 가정).

awk 'NR>1 && NR < 3' file

또는 Perl에서 :

perl -ne 'print if $.>1 && $.<3' file

줄이 몇 줄인지 모르는 경우 다음을 사용하여 즉시 계산할 수 있습니다 grep(빈 줄은 계산되지 않으며 줄 grep -c '' file을 세는데도 사용됨).

awk -vm="$(grep -c . file2.txt)" 'NR>1 && NR<m' file2.txt

3

이 솔루션을 사용해보십시오 :

tail -n +2 name_of_file | head -n-1

커스터마이징

당신은 쉽게 N 첫번째 라인은 변경 삭제를 적용 할 수 +2의를 tail;
또는 변경 마지막 n 라인 삭제 -1의를 head.


이 솔루션은 첫 번째 줄을 인쇄하므로 올바르지 않습니다.
xhienne

1
@xhienne 죄송합니다. 실수였습니다. "꼬리"의 매개 변수로 2 대신 1을 썼습니다. 이제 작동합니다, 감사합니다! :)
Gabrer

1

사용 awk:

< inputfile awk 'NR>1 {print r}; {r=$0}' > outputfile
  • < inputfile:의 내용을 리디렉션 inputfile에 대한 awk'들stdin
  • > outputfile:의 내용을 재 지정 awkstdout로를outputfile
  • NR>1: 처리중인 레코드 수가 1보다 큰 경우에만 다음 조치를 실행합니다.
  • {print r}: 변수의 내용을 인쇄합니다 r
  • {r=$0}: 처리중인 레코드의 컨텐츠를 변수에 지정합니다. r

따라서 awk스크립트를 처음 실행할 때 첫 번째 작업 블록이 실행되지 않고 두 번째 작업 블록이 실행되고 레코드의 내용이 변수에 할당됩니다 r. 두 번째 실행에서 첫 번째 작업 블록이 실행되고 변수의 내용 r이 인쇄되므로 이전 레코드가 인쇄됩니다. 이것은 처리 된 각 라인을 인쇄하는 효과가 있지만 첫 번째 라인과 마지막 라인을 인쇄합니다.


첫 번째 줄을 제외하지 않았습니다. NR == 2에서는에 저장된 첫 번째 입력 행을 인쇄합니다 r.
xhienne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.