여러 데이터베이스 가치가있는 ~ 23000 행 SQL 덤프가 있습니다. 이 파일의 특정 섹션 (예 : 단일 데이터베이스의 데이터)을 추출하여 새 파일에 배치해야합니다. 원하는 데이터의 시작 및 끝 줄 번호를 모두 알고 있습니다.
16224와 16482 사이의 파일에서 모든 줄을 추출하여 새 파일로 리디렉션하는 유닉스 명령 (또는 일련의 명령)을 아는 사람이 있습니까?
여러 데이터베이스 가치가있는 ~ 23000 행 SQL 덤프가 있습니다. 이 파일의 특정 섹션 (예 : 단일 데이터베이스의 데이터)을 추출하여 새 파일에 배치해야합니다. 원하는 데이터의 시작 및 끝 줄 번호를 모두 알고 있습니다.
16224와 16482 사이의 파일에서 모든 줄을 추출하여 새 파일로 리디렉션하는 유닉스 명령 (또는 일련의 명령)을 아는 사람이 있습니까?
답변:
sed -n '16224,16482p;16483q' filename > newfile
로부터 나오지 매뉴얼 :
p- 패턴 공간을 인쇄합니다 (표준 출력으로). 이 명령은 일반적으로 -n 명령 줄 옵션과 함께 사용해야합니다.
n- 자동 인쇄가 비활성화되지 않은 경우 패턴 공간을 인쇄 한 다음 패턴 공간을 다음 입력 라인으로 교체하십시오. 더 이상 입력이 없으면 더 이상 명령을 처리하지 않고 sed가 종료됩니다.
q-
sed
더 이상의 명령이나 입력을 처리하지 않고 종료 합니다. -n 옵션으로 자동 인쇄를 비활성화하지 않으면 현재 패턴 공간이 인쇄됩니다.
sed 스크립트의 주소는 다음 형식 중 하나 일 수 있습니다.
number 줄 번호를 지정하면 입력에서 해당 줄만 일치합니다.
주소 범위는 쉼표 (,)로 구분 된 두 주소를 지정하여 지정할 수 있습니다. 주소 범위는 첫 번째 주소가 일치하는 위치부터 시작하여 두 번째 주소가 일치 할 때까지 계속됩니다.
sed -n '16224,16482p;16483q' filename
입니다. 그렇지 않으면 sed는 끝까지 (또는 적어도 내 버전에서는) 스캔을 계속합니다.
sed -n '16224,16482 p' orig-data-file > new-file
여기서 16224,16482는 시작 줄 번호와 끝 줄 번호입니다. 이것은 1 인덱스입니다. -n
입력을 출력으로 에코하는 것을 억제합니다. 숫자는 다음 명령이 작동하게하는 라인 범위를 나타냅니다. 명령 p
은 관련 행을 인쇄합니다.
머리 / 꼬리를 사용하여 매우 간단합니다.
head -16482 in.sql | tail -258 > out.sql
sed를 사용하여 :
sed -n '16482,16482p' in.sql > out.sql
awk 사용 :
awk 'NR>=10&&NR<=20' in.sql > out.sql
tail
.
sed -n 16224,16482p' in.sql >out.sql
하고 awk 명령은awk 'NR>=16224&&NR<=16482' in.sql > out.sql
head -16482 in.sql | tail -$((16482-16224)) >out.sql
계산을 bash로 남겨 두는 것을 알 가치가 있습니다.
tail -n +16224
계산을 줄이기 위해 사용할 수도 있습니다
'vi'를 사용하고 다음 명령을 사용할 수 있습니다.
:16224,16482w!/tmp/some-file
또는
cat file | head -n 16482 | tail -n 258
편집 :-설명을 추가하기 위해 head -n 16482 를 사용 하여 첫 16482 줄을 표시 한 다음 tail -n 258 을 사용 하여 첫 번째 출력에서 마지막 258 줄을 가져옵니다.
cat
명령이 필요하지 않습니다 . head
파일을 직접 읽을 수 있습니다. 1이 충분한 2 (그림에 표시된 3) 명령을 사용하기 때문에 많은 대안보다 속도가 느립니다.
cat
). 다른 솔루션에는 최소한 몇 분이 필요합니다. 또한 GNU에서 가장 빠른 변형은 다음과 같습니다 tail -n +XXX filename | head XXX
.
다른 접근 방식이 있습니다 awk
.
awk 'NR==16224, NR==16482' file
파일이 크면 exit
마지막으로 원하는 행을 읽은 후 좋을 수 있습니다 . 이렇게하면 불필요하게 다음 줄을 읽지 않습니다.
awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file
awk 'NR==16224, NR==16482; NR==16482 {exit}' file
print; exit
. 감사 !
awk 'NR==16224, NR==16482; NR==16482 {exit}' file
cat dump.txt | head -16224 | tail -258
트릭을해야합니다. 이 접근법의 단점은 꼬리에 대한 인수를 결정하고 '사이에'에 끝 줄을 포함 시킬지 여부를 설명하기 위해 산술을 수행해야한다는 것입니다.
cat
명령이 필요하지 않습니다 . head
파일을 직접 읽을 수 있습니다. 1이 충분한 2 (그림에 표시된 3) 명령을 사용하기 때문에 많은 대안보다 속도가 느립니다.
| tail -$((16482 - 16224))
.
boxxar의 어깨에 서서 나는 이것을 좋아합니다.
sed -n '<first line>,$p;<last line>q' input
예 :
sed -n '16224,$p;16482q' input
$
수단 "마지막 줄에"첫 번째 명령은 수 있도록 sed
라인으로 시작하는 모든 라인을 인쇄 16224
하고, 두 번째 명령 차종은 sed
종료 후 라인을 인쇄 16428
. (추가 1
에 대한 q
boxxar의 솔루션 - 범위하는 것은 필요하지 않는 것 같습니다.)
끝 줄 번호를 두 번 지정할 필요가 없기 때문에이 변형이 마음에 듭니다. 그리고 사용 $
이 성능에 해로운 영향을 미치지 않는다는 것을 측정했습니다 .
빠르고 더러운 :
head -16428 < file.in | tail -259 > file.out
아마도 최선의 방법은 아니지만 작동해야합니다.
BTW : 259 = 16482-16224 + 1.
필자는 splitter 라는 Haskell 프로그램을 작성했습니다. 이는 내 릴리스 블로그 게시물을 읽으십시오 .
다음과 같이 프로그램을 사용할 수 있습니다.
$ cat somefile | splitter 16224-16482
그리고 그것이 전부입니다. Haskell을 설치해야합니다. 다만:
$ cabal install splitter
그리고 당신은 끝났습니다. 이 프로그램이 도움이 되길 바랍니다.
splitter
표준 입력에서 읽기 전용? 어떤 의미에서는 중요하지 않습니다. cat
명령은 수행되지 않거나 여부를 불필요. 어느 사용 splitter 16224-16482 < somefile
(이 파일 이름 인수를 경우) splitter 16224-16482 somefile
.
명령 행에서 확인할 수 있습니다 :
cat filename|sed 'n1,n2!d' > abc.txt
예를 들어 :
cat foo.pl|sed '100,200!d' > abc.txt
cat
이들 중 하나 에서 명령이 필요하지 않습니다 . sed
파일 자체를 완벽하게 읽을 수 있거나 파일에서 표준 입력을 리디렉션 할 수 있습니다.
나는 머리 / 꼬리 트릭을 게시하려고했지만 실제로는 아마도 이맥스를 발사했을 것입니다. ;-)
새 출력 파일을 열고 ctl-y 저장
무슨 일이 일어나고 있는지 보자.
디렉토리를 포함하도록 PATH를 업데이트하거나 PATH에 이미 포함 된 디렉토리에 배치 할 수있는 한 명령 줄에서 실행할 수있는 작은 bash 스크립트를 작성했습니다.
사용법 : $ pinch filename start-line end-line
#!/bin/bash
# Display line number ranges of a file to the terminal.
# Usage: $ pinch filename start-line end-line
# By Evan J. Coon
FILENAME=$1
START=$2
END=$3
ERROR="[PINCH ERROR]"
# Check that the number of arguments is 3
if [ $# -lt 3 ]; then
echo "$ERROR Need three arguments: Filename Start-line End-line"
exit 1
fi
# Check that the file exists.
if [ ! -f "$FILENAME" ]; then
echo -e "$ERROR File does not exist. \n\t$FILENAME"
exit 1
fi
# Check that start-line is not greater than end-line
if [ "$START" -gt "$END" ]; then
echo -e "$ERROR Start line is greater than End line."
exit 1
fi
# Check that start-line is positive.
if [ "$START" -lt 0 ]; then
echo -e "$ERROR Start line is less than 0."
exit 1
fi
# Check that end-line is positive.
if [ "$END" -lt 0 ]; then
echo -e "$ERROR End line is less than 0."
exit 1
fi
NUMOFLINES=$(wc -l < "$FILENAME")
# Check that end-line is not greater than the number of lines in the file.
if [ "$END" -gt "$NUMOFLINES" ]; then
echo -e "$ERROR End line is greater than number of lines in file."
exit 1
fi
# The distance from the end of the file to end-line
ENDDIFF=$(( NUMOFLINES - END ))
# For larger files, this will run more quickly. If the distance from the
# end of the file to the end-line is less than the distance from the
# start of the file to the start-line, then start pinching from the
# bottom as opposed to the top.
if [ "$START" -lt "$ENDDIFF" ]; then
< "$FILENAME" head -n $END | tail -n +$START
else
< "$FILENAME" tail -n +$START | head -n $(( END-START+1 ))
fi
# Success
exit 0
wc
명령으로 인해 파일을 두 번 읽습니다 . 특히 기가 바이트 파일에서 디스크 대역폭을 낭비합니다. 모든 종류의 방법으로, 이것은 잘 문서화되어 있지만 엔지니어링 오버 킬입니다.
수락 응답의 -n이 작동합니다. 기울어 질 경우를 대비 한 다른 방법이 있습니다.
cat $filename | sed "${linenum}p;d";
이것은 다음을 수행합니다.
cat file | sed
로 더 잘 작성sed file
우리는 텍스트 파일에서 텍스트 줄을 추출하는 것에 대해 이야기하고 있기 때문에 특정 패턴과 일치하는 모든 줄을 추출하려는 특별한 경우를 제공합니다.
myfile content:
=====================
line1 not needed
line2 also discarded
[Data]
first data line
second data line
=====================
sed -n '/Data/,$p' myfile
[데이터] 줄과 나머지를 인쇄합니다. 텍스트를 line1에서 패턴까지 원하는 경우 sed -n '1, / Data / p'myfile을 입력하십시오. 또한 두 가지 패턴을 알고 있으면 (텍스트에서 더 독창적 임) 범위의 시작 및 끝 줄을 모두 일치로 지정할 수 있습니다.
sed -n '/BEGIN_MARK/,/END_MARK/p' myfile