나는 bash 쉘을 사용하고 있습니다. 줄 번호가 있는 파일이 있는 경우
1
4
7
9
첫 번째 요소가 숫자이고 그 뒤에 텍스트 문자열이 오는 또 다른 라인 파일
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
awk
첫 번째 숫자가 첫 번째 파일에 속하는 경우에만 두 번째 파일에서 줄을 추출하는 명령을 어떻게 작성할 수 있습니까? 위의 예에서는 다음과 같은 결과가 나올 것으로 예상됩니다.
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
나는 이것을 시도했다
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
그러나 세 번째 파일에서는 아무것도 생성되지 않습니다.
답변1
,
두 번째 파일은 쉼표로 구분되므로 명령줄 옵션을 사용하여 awk 필드 구분 기호를 -로 설정해야 합니다 .-F
awk -F, 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
또는 FS
내장 변수를 통해:
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file FS=, /tmp/second_file > /tmp/third_file
후자의 접근 방식을 사용하면 첫 번째 파일이 쉼표로 구분되지 않고 여러 필드가 있는 경우를 처리할 수 있습니다.
답변2
사용행복하다(이전 Perl_6)
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] == any(@a);' file.csv
#OR
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] ~~ any(@a);' file.csv
Raku는 Perl 계열의 프로그래밍 언어입니다. 숫자 목록을 가져 와서 BEGIN
배열에 저장할 때 @a
. 그런 다음 플래그는 -ne
자동으로 인쇄하지 않고 명령줄에서 파일을 읽습니다( awk
유사한 동작).
여기서 행은 테마 변수( $_
)(쉼표 위) 로 읽혀지고 split
첫 번째 요소( )가 얻어집니다. 숫자 항등 연산자(첫 번째 코드 예) 또는 Raku의 스마트 일치 연산자를 사용하여 [0]
이러한 요소를 비교하세요. 연산자 오른쪽에 있는 배열은 노드가 됩니다. 조건이 충족되면 조건에 따라 행이 출력됩니다.==
~~
@a
any()
if
put
입력 예:
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
출력 예( nbr_list.txt
1,4,7,9로 구성된 파일 사용):
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
조인 포인트는 자동으로 스레드되기 때문에 흥미롭습니다. 위의 문제에 대해서는 one()
커넥터가 더 효율적으로 작동할 수도 있습니다.
또 다른 방법은 집합을 사용하는 것입니다. 즉, 줄 번호를 s로 변환하는 것 Set
입니다 Int
. 데이터는 행 단위로 읽혀지며, 각 첫 번째 열은 강제로 변환되어 집합의 요소 Int
인지 확인됩니다 . (elem)
infix (elem)
또는 infix , (유니코드 기호)는 다음 코드에서 사용될 수 있습니다.∈
~$ raku -ne 'BEGIN my $set1 = Set.new("nbr_list.txt".IO.lines.map: *.Int); \
.put if $_.split(",").[0].Int (elem) $set1;' file
Raku 세트는 고유한 값만 포함할 수 있으므로(즉, 입력이 "고유"함) 두 번째 예에서는 파일의 중복 항목을 삭제합니다 "nbr_list.txt"
. 이것이 실제로 OP가 원하는 것일 수 있습니다.
https://docs.raku.org/type/Junction
https://docs-stage.raku.org/type/Junction
https://raku.org
답변3
이 작업을 "결합"이라고 합니다. coreutils에는 join
텍스트 파일을 연결하는 도구가 있습니다 .
join -t, -j1 --nocheck-order first_file second_file
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
설명하다:
-t,
- 필드 구분자로 쉼표를 사용하세요.-j1
- 첫 번째 필드 추가--nocheck-order
- Join을 사용하려면 파일을 정렬해야 하지만 숫자 정렬은 좋아하지 않습니다. 따라서 사전식 순서를 확인하고 "10"이 앞에 오는 "9"에 대해 불평하는 것을 방지합니다. 두 파일의 첫 번째 열이 동일한 알고리즘을 사용하여 정렬되는 한 여전히 작동합니다.