두 개의 파일이 있습니다. 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
.sed
sed
sed 's/$/p/' lines.list | sed -n -f /dev/stdin file.txt
여기에서는 먼저 this 와 같은 명령으로 구성된 스크립트를 sed
만들고 각 줄 끝에 삽입 하면 됩니다 . 그런 다음 스크립트는 스크립트를 읽고 텍스트 파일과 함께 입력으로 적용하는 파이프 다음의 두 번째 로 전송됩니다.sed
1p
4p
p
sed
-f /dev/stdin
이렇게 하려면 각 파일을 한 번만 읽어야 합니다.
를 사용하여 awk
줄 번호를 연관 배열의 키로 읽은 다음 다른 파일을 읽을 때 현재 줄 번호가 이전에 배열에 입력된 줄 번호 중 하나인지 확인하세요.
awk 'FNR == NR { lines[$0]; next } (FNR in lines)' lines.list file.txt
에서 awk
특수 변수 NR
및 FNR
는 각각 지금까지 읽은 총 레코드(라인) 수와 현재 파일에서 읽은 총 레코드(라인) 수입니다. NR
같음 인 경우 FNR
첫 번째 입력 파일에서 읽고 $0
현재 줄을 키로 사용하여 배열 항목을 만들고(값이 지정되지 않음) 즉시 다음 입력 줄로 점프합니다.
현재 줄을 읽고 있지 않다면 현재 파일의 줄 번호가 배열의 키인지 FNR in lines
테스트 합니다 . 그렇다면 현재 줄이 인쇄됩니다.FNR
lines
이 유틸리티는 실제로 다른 도구의 강력한 지원 없이 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.
답변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'