내 파일에 테스트 데이터가 있습니다.text.txt
a
b
test
test2
1,2
3,3
test + 2 줄부터 파일을 출력하고 싶습니다. 에서 사용할 수 있는 원라이너로 이것이 필요합니다 gnuplot
. 다음을 생각해냈습니다.
awk -v linestart=$(awk '$0~"test" {a=NR}END{print a+2}' $filename) 'BEGIN{FS=",";OFS="\t";lines}NR>=linestart{print $1, $2}' $filename
하지만 어떻게든 파일 내용을 두 가지 모두에 공급해야 하는데 awk
방법을 모르겠습니다. 그래서 해결책을 알아냈는데, $filename
어떻게 들어가야 하는지 문제가 생겼습니다 $filename
.
내 생각은 이렇습니다.
echo "test.txt" | read filename | awk -v linestart=$(awk '$0~"test" {a=NR}END{print a+2}' $filename) 'BEGIN{FS=",";OFS="\t";lines}NR>=linestart{print $1, $2}' $filename
그러나 이것은 작동하지 않습니다.
위의 작업을 어떻게 수행할 수 있습니까? 명백한 문제는 인쇄를 실행하기 전에 인쇄를 시작할 줄 번호를 알아야 한다는 것입니다 awk
. 나는 또한 몇 가지에 대해 생각하고 있습니다:
awk 'BEGIN{FS=",";OFS="\t";lines=100000}{if ($0~"test"){lines=NR+2}; if(NR>=lines){print $1, $2}}'
하지만 매우 추악하고 일반적이지 않기 때문에 시도조차 하지 않았습니다. 변수를 lines
항상 충분히 크게 만들어야 합니다. 그렇다면 일반 텍스트 파일 파이프에서 작동하는 우아한 솔루션이 있습니까? 아니면 다른 경우에는 파일 이름을 파이프에 밀어넣는 방법이 있습니까?
답변1
사용 ed
:
$ printf '%s\n' '/^test/+2,$p' | ed -s file
1,2
3,3
ed
편집기 에서 이 명령은 일치하는 줄 너머의 두 줄을 줄의 끝( )까지 /^test/+2,$p
인쇄합니다( ).p
^test
$
사용 awk
:
$ awk '/^test/ { flag = 1; count = 1 }; (flag == 1 && count <= 0); { count-- }' file
1,2
3,3
flag
여기서 가 1이고 count
0보다 작거나 같으면 한 줄이 인쇄됩니다. 이 플래그는 ^test
입력 데이터에서 패턴이 일치할 때 1로 설정되고, count
출력이 시작되기 전에 건너뛸 줄 수로도 설정됩니다(현재 줄은 계산하지 않음). count
모든 라인의 값이 감소됩니다.
약간 다른 접근 방식 awk
:
$ awk '/^test/ { getline; while (getline > 0) print }' file
1,2
3,3
여기서는 패턴을 일치시킨 후 즉시 다음 입력 줄을 읽고 버립니다. 그런 다음 while 루프를 사용하여 파일의 나머지 부분을 읽고 읽은 각 줄을 인쇄합니다.
완전히 동일한 방법이지만 다음을 사용합니다 sed
.
$ sed -n -e '/^test/ { n' -e ':again' -e 'n; p; b again' -e '}' file
1,2
3,3
패턴을 일치시킨 후 다음 줄을 읽고 삭제한 다음( n
), 루프를 입력하여 각 줄을 읽고 인쇄합니다( n; p;
). 루프는 라벨 again
과 해당 라벨로의 분기/점프( ) 로 구성됩니다 b again
.
답변2
test
데이터가 2행 이후에 시작 하고 위에 행이 더 이상 없다는 것을 알고 있으면 test
다음과 같이 할 수 있습니다.
awk '/^test$/ { f=1 } f && f++ > 2' filename
또는 이 데이터를 Gnuplot으로 보내려면 다음과 같은 파이프라인을 통해 수행하는 것을 고려할 수 있습니다.
(
echo "set datafile separator ','"
echo "plot '-' using 1:2 with lines"
awk '/^test$/ { f=1 } f && f++ > 2' filename
echo "e"
) | gnuplot -persist
답변3
항상 false인 끝 조건과 행을 건너뛰는 시작 조건이 있는 범위를 사용 start, end
하면 이를 달성 할 수 있습니다.
awk '/test/ && getline && getline, 0'
답변4
$ awk '/test/{n=NR} n && NR>n' file
1,2
3,3
$ awk '/test/{n=NR+1} n && NR>n' file
3,3
당신은 또한 볼 수 있습니다https://stackoverflow.com/a/17914105/1745001