400,000줄의 큰 파일 두 개가 있습니다. 두 번째 파일의 열 1과 첫 번째 파일의 열 1을 재귀적으로 비교하고 싶습니다. 일치하면 전체 줄을 인쇄하고 싶습니다. 정렬된 파일입니다.
file 1:
name values
aaa 10
aab acc
aac 30
aac abc
file2:
aaa
aac
aac
aad
파일에 400,000줄이 포함되어 있으므로 처리하는 데 시간이 걸립니다.
내 현재 솔루션은 다음과 같습니다
#!/bin/ksh
while read line
do
var=`echo $line `
grep "$var" file1 >> /dev/null
if [ $? -eq 0 ]
then
grep "$var" file1 >> present
else
echo " $line missing " > missing
fi
done < "file2"
여기에서 사용하는 것 때문에 grep
값이 예상한 열 1이 아닌 파일 1의 어딘가에 나타날 수 있으며 그런 일이 발생하지 않기를 바랍니다.
내 예상 솔루션:
- 두 번째 파일만 첫 번째 파일의 열 1과 비교합니다(이렇게 해도 시간이 오래 걸립니다).
- 파일 포인터가 있는 스크립트를 사용하여
perl
파일의 두 열을 비교합니다. 문자열이 일치하면 인쇄하십시오. 그렇지 않고 첫 번째 파일의 열 1이 두 번째 파일의 열보다 크면 파일 2가 증가되어 비교됩니다. 반대의 경우 파일 1의 열 1을 증가시키고 비교합니다.
답변1
join file1 file2
기본적으로 각 파일에 대해 열 1을 사용하고 그 중 누락된 행을 무시합니다. 이는 원하는 것입니다. 또한 파일을 정렬해야 하는데 이는 이미 그렇습니다.
답변2
수량이라면고유한의 요소가 file2
너무 크지 않은 경우 실행 가능한 솔루션은 두 개의 파일을 처리하는 고전적인 접근 방식을 사용하여 awk
먼저 열 1에 있는 유일한 요소의 배열을 만든 file2
다음 file1
열 1이 배열의 구성원인지 테스트하는 것입니다. 지금
awk 'FNR==NR {a[$1]++}; FNR!=NR && a[$1]' file2 file1
연관 배열을 사용하는 동등한 접근 방식 bash 4+
은 다음과 같습니다.
#!/bin/bash
declare -A a
while read col1 _ ; do
((a[$col1]++))
done < file2
while IFS= read -r line; do
# compare only with 1st column of second file
read -r col1 _ <<< "$line"
[[ -n "${a[$col1]}" ]] && printf "$line\n"
done < file1
답변3
이것이 당신이 찾고 있는 것입니까? 나는 cut
목록을 각각 하나의 열을 포함하는 배열로 분할하는 데 익숙합니다. 이는 열이 탭으로 구분되어 있다고 가정합니다. options 를 지정하여 구분 기호 자르기 사용을 변경할 수 있습니다 -d
. 밑줄로 분할: cut -d '_'
.
#!/bin/bash
FILE1='somefile'
FILE2='someotherfile'
# File 1, column 1
f1c1=($(cut -f1 -s $FILE1))
# File 1, column 2
#f1c2=($(cut -f2 -s $FILE1))
# File 2, column 1
f2c1=($(cut -f1 -s $FILE2))
# File 2, column 2
#f2c2=($(cut -f2 -s $FILE2))
# Looping through all items in file 1 column 1
for x in "${f1c1[@]}"
do
# For each item in f1c1, check all items in f2c1 for a match
for y in "${f2c1[@]}"
do
if [[ $x == $y ]]
then
# The items matched!
echo $x
# Breaking out of the loop (no need to check for more than one
# match, right?)
break
fi
done
done