sed, grep 또는 awk를 사용하여 다른 파일의 줄 번호를 기반으로 파일의 특정 줄을 유지하는 방법

sed, grep 또는 awk를 사용하여 다른 파일의 줄 번호를 기반으로 파일의 특정 줄을 유지하는 방법

두 개의 파일이 있습니다. File1일부 문장이 포함되어 있으며 File2유지하려는 줄 번호가 포함되어 있습니다 File1.

예를 들어, File1:

He is a boy.
She is a cook.
Okay.
She went to school.
She is pretty.

File2:

1
4

산출:

He is a boy.
She went to school.

sed, 또는 를 사용하여 grep이를 수행할 수 있는 방법이 있습니까 awk? 줄 번호를 수동으로 쓰고 싶지 않습니다.여기.

답변1

숫자 목록을 일련의 명령으로 변환하고 단일 호출로 편집 스크립트로 실행할 수 있습니다 sed.sedsed

sed 's/$/p/' lines.list | sed -n -f /dev/stdin file.txt

여기에서는 먼저 this 와 같은 명령으로 구성된 스크립트를 sed만들고 각 줄 끝에 삽입 하면 됩니다 . 그런 다음 스크립트는 스크립트를 읽고 텍스트 파일과 함께 입력으로 적용하는 파이프 다음의 두 번째 로 전송됩니다.sed1p4ppsed-f /dev/stdin

이렇게 하려면 각 파일을 한 번만 읽어야 합니다.


를 사용하여 awk줄 번호를 연관 배열의 키로 읽은 다음 다른 파일을 읽을 때 현재 줄 번호가 이전에 배열에 입력된 줄 번호 중 하나인지 확인하세요.

awk 'FNR == NR { lines[$0]; next } (FNR in lines)' lines.list file.txt

에서 awk특수 변수 NRFNR는 각각 지금까지 읽은 총 레코드(라인) 수와 현재 파일에서 읽은 총 레코드(라인) 수입니다. NR같음 인 경우 FNR첫 번째 입력 파일에서 읽고 $0현재 줄을 키로 사용하여 배열 항목을 만들고(값이 지정되지 않음) 즉시 다음 입력 줄로 점프합니다.

현재 줄을 읽고 있지 않다면 현재 파일의 줄 번호가 배열의 키인지 FNR in lines테스트 합니다 . 그렇다면 현재 줄이 인쇄됩니다.FNRlines


이 유틸리티는 실제로 다른 도구의 강력한 지원 없이 grep이러한 작업을 수행하기 위한 것이 아닙니다 . 내용이 주어진 패턴과 일치하는(또는 일치하지 않는) 텍스트 파일에서 행을 추출합니다. 따라서 패턴은 줄 번호가 아닌 줄과 일치해야 합니다.

다음 내용은 오락 목적으로만 제공되며 실제로 이 문제를 해결하는 방법에 대한 조언으로 받아들여서는 안 됩니다.

당신은 할 수끼워 넣다줄 번호 및 grep사용법

grep -n '.*' file.txt

그러면 파일의 모든 줄 시작 부분에 줄 번호가 삽입되고 그 뒤에 :줄의 원래 내용이 삽입됩니다.

그런 다음 솔루션과 마찬가지로 sed패턴 파일을 수정하여 이러한 특정 숫자 선택과 일치할 수 있습니다.

sed 's/.*/^&:/' lines.list

^1:그러면 및 와 같은 정규식이 출력되며 ^4:, 각각은 줄 시작 부분의 특정 줄 번호와 일치합니다.

그런 다음 이러한 표현식을 사용할 수 있습니다 grep(여기서는 절차적 대체의 도움으로). 마지막으로 다음을 사용하여 임시 줄 번호를 제거합니다 cut.

grep -n '.*' file.txt | grep -f <(sed 's/.*/^&:/' lines.list) | cut -d : -f 2-

...하지만 이는 너무 인위적이어서 합리적인 해결책이라고 볼 수도 없습니다.


위의 각 솔루션은 항상 선택한 줄을 텍스트 파일에 나타나는 순서대로 표시합니다. 파일에 나타나는 순서대로 행을 출력하려면 sed(또는 awk아래 참조)을 사용할 수 있습니다.

sed 's/$/p/' lines.list | ed -s file.txt

p다시 말하지만, 각 줄의 끝에 간단히 추가하여 줄 번호 파일에서 편집 스크립트를 만듭니다.

그런 다음 스크립트는 명령 입력으로 ed편집기에 전달되며, 편집기는 명령을 텍스트 파일에 순차적으로 적용합니다.

시험:

$ cat lines.list
4
1
$ sed 's/$/p/' lines.list | ed -s file.txt
She went to school.
He is a boy.

sed아래의 해당 프로그램과 마찬가지로 전체 파일을 메모리로 읽어 들 입니다 awk.

awk 'NR == FNR { lines[FNR] = $0; next } { print lines[$0] }' file.txt lines.list

이전 솔루션과 비교하여 입력 파일이 전환되었습니다 awk. 이를 통해 먼저 lines텍스트 파일을 한 줄씩 배열로 읽은 다음 줄 번호가 있는 파일을 읽는 동안 무작위로 줄을 선택할 수 있습니다.

답변2

파일이 줄 번호 file.txt이고 포함되어 있다고 가정합니다. lines.txt사용 xargs:

# extract digit sequences from lines.txt and make sed arguments
sed 's/[^[:digit:]]*\([[:digit:]]\+\)[^[:digit:]]*/-e \1p /g' lines.txt \
    | xargs /bin/sh -c '[ $# -gt 0 ] && sed -n "$@" file.txt' sh

답변3

사용행복하다(이전 Perl_6)

#Sample Input:

~$ cat data.txt
He is a boy.
She is a cook.
Okay.
She went to school.
She is pretty.

색인을 보여주는 연속 예:

~$ raku -e '.put for lines[ 0,3 ];'  data.txt
He is a boy.
She went to school.

#Take line-number index inline (subtract 1 to make zero-indexed):

~$ raku -e 'my @index = <1 4>; .put for lines[ @index.map: *-1 ];' data.txt
He is a boy.
She went to school.

인덱스를 파일 경로로 사용하여 명령줄에서 데이터를 가져옵니다.

~$ raku -e 'my @ind = "/path/to/index.txt".IO.lines; 
            .put for lines[ @index.map: *-1 ];'  data.txt
He is a boy.
She went to school.

명령줄에서 다음 두 파일을 가져옵니다( data.txt그런 다음 index.txt).

~$  raku -e 'my @data  = @*ARGS[0].IO.lines;
             my @index = @*ARGS[1].IO.lines;
             .put for @data[ @index.map: *-1 ];'  data.txt  index.txt
He is a boy.
She went to school.

https://docs.raku.org
https://raku.org

답변4

File2의 대상 행 번호가 오름차순인 경우 이 방법을 사용할 수 있습니다.

sed -e 's/$/b/;$a d' < File2 |
sed -f - File1

일련의 sed 명령 생성

1b
4b
d

File2에 주어진 순서대로 File1의 행을 인쇄하는 일반적인 경우에는 아래 두 가지 중 하나를 사용합니다.

awk를 사용하여 File1의 줄 번호와 값을 줄 내용으로 사용하여 연관 배열을 생성합니다. 하지만 File2에 언급된 줄과 일치하지 않는 추가 줄만 저장됩니다. Fikle2의 대상 행 번호부터 시작하여 수치적으로 증가하는 인덱스로 키가 지정되고 값 필드가 대상 행 번호인 또 다른 배열을 유지합니다.

awk '
{if (X) c[b[FNR]]=$0; else b[a[NR]=$1]=$1}
END {for (i=1; i in a; i++) print c[a[i]]}
' File2 X=1 File1

Slurp 모드 -z에서 GNU sed를 사용하십시오. 하지만 먼저 File2의 내용을 보는 명령을 생성합니다.

sed -e 's:.*:s/^(.*\\n){&}/\\1\\d0/M;P;g:' File2 |
sed -zEn -e h -f - File1 | tr -d '\0'

관련 정보