인쇄 방법앞줄과뒤에 줄번째 줄

인쇄 방법앞줄과뒤에 줄번째 줄

질문은여기패턴 일치 이전과 이후에 몇 줄을 요청합니다.

하지만 여기서 목표는 줄 번호를 가져와서 파일에서 그 앞과 뒤의 일부 줄을 가져오는 것입니다.

예:

seq 10
1
2
3
4
5
6
7
8
9
10

줄 번호가 6인 경우 해당 줄 앞에 4개의 숫자, 해당 줄 뒤에 3개의 숫자를 제공해야 합니다. 그건

2
3
4
5
6
7
8
9

답변1

z=6   # focus line
x=4   # lines before
y=3   # lines after

start=$(( z - x ))
end=$(( z + y ))

사용 sed:

seq 10 | sed -n "$start,${end}p"
2
3
4
5
6
7
8
9

이것은 단순히 인쇄할 라인의 명시적인 범위와 함께 의 print( p) 명령을 사용합니다. sed다른 줄은 를 사용하여 무시됩니다 -n.

사용 awk:

seq 10 | awk -v start="$start" -v end="$end" 'NR >= start { print } NR >= end { exit }'
2
3
4
5
6
7
8
9

이는 Stéphane Chazelas의 답변과 유사하지만 awk; 스크립트는 start행 수를 읽은 후 입력 행 출력을 시작합니다 . 행 수 만큼 end스크립트가 종료됩니다.

x두 대안 모두 line 앞의 줄 에서 시작하여 line 뒤의 z줄로 끝나는 입력 데이터의 일부를 표시합니다 .yz

답변2

POSIX 쉘의 경우:

$ before=4 after=3 line=6
$ seq 10 | sed "$((line-before)),\$!d; $((line+after))q"
2
3
4
5
6
7
8
9

다음으로 번역:

  • !범위에서 ( )를 제외한 모든 줄을 삭제합니다.라인 - 이전끝까지 ( $).
  • 에 있어라인 + 이후번째

그렇게 하면 우리는 과거의 내용을 읽는 데 신경 쓰지 않아도 됩니다.라인 + 이후번째 줄.

그러나 이는 데이터를 공급하는 명령이 sed바람직할 수도 있고 그렇지 않을 수도 있는 데이터 전송을 계속하면 SIGPIPE로 중단된다는 것을 의미합니다.

답변3

완전성을 위해 :

$ l=60;seq 100 |head -n$((l+3)) |tail -n+$((l-4))
56
57
58
59
60
61
62
63

소문과 다양한 벤치마크에 따르면 head + tail 조합이 다른 어떤 도구보다 훨씬 빠르다고 합니다.

$ a=1000000000
$ time seq $a |awk 'NR>=499998{print}NR >= 500004 { exit }' 
499998
499999
500000
500001
500002
500003

real    0m0.158s
user    0m0.152s
sys 0m0.004s

$ time seq $a |sed -n "499998,500003p"
499998
499999
500000
500001
500002
500003

real    1m30.249s
user    1m21.284s
sys 0m12.312s

$ time seq $a |sed "$((500000-2)),\$!d; $((500000+3))q"  #Stephan's Solution
499998
499999
500000
500001
500002
500003

real    0m0.052s
user    0m0.044s
sys 0m0.004s

$ time seq $a |head -n$((500000+3)) |tail -n+$((500000-2))
499998
499999
500000
500001
500002
500003

real    0m0.024s
user    0m0.024s
sys 0m0.004s

$ time seq $a |sed -n "499998,500003p;500004q"
499998
499999
500000
500001
500002
500003

real    0m0.056s
user    0m0.048s
sys 0m0.004s

답변4

# define line range constants
before=4
  line=6
 after=3

# setup the sed commands s.t. pattern space holds $before number
# of lines before we hit the line number $line and $after after
s='$!N'
p=`seq -s "$s"   "$before"`
a=`seq -s "$s" 0 "$after"`

N=${p//[0-9]/;}
n=${a//[0-9]/;}

# main...
seq 10 |
sed -e "
   1{ $N }
   \$d;N
   $line!D
   $n;q
"

또 다른 방법은 파일을 후루룩 마시고 필드(현재 줄)가 에 있도록 FS를 설정하는 것입니다 . 남은 것은 6번째 줄과 4개 요소 앞, 3줄 뒤를 중심으로 잘라내는 것입니다.\n@F

perl -alF\\n -0777ne '$,=$\;print @F[6-4-1..6+3-1]' yourfile

결과

2
3
4
5
6
7
8
9

관련 정보