파일의 각 줄에서 첫 번째 단어를 가져오는 잘라내기 명령이 있습니다. 그런 다음 cut 명령의 각 단어를 foreach에 넣고 싶습니다. 그런 다음 foreach 본문 내에서 grep 명령을 실행하여 다른 파일에서 해당 단어를 grep하려고 합니다.
이 같은:
@array = (cut /tmp/10218.after -f1);
foreach $word (@lines) {
grep $word /tmp/10218.before;
}
분명히 @array 할당이 작동하지 않습니다. 이 문제를 어떻게 해결할 수 있나요?
나는 그것이 무엇인지, 어느 것이 가장 좋고 충분히 좋은지 모르는 방법이 많이 있다고 확신합니다.
답변1
배쉬에서
while read -r word
do
grep -q "$word" file.before
if [ $? -ne "0" ]
then
echo "$word not in file"
fi
done < <(cut -f1 -d" " file.after)
grep 은 -q
조용히 하라고 지시한 다음 $?
일치하는 항목이 있는지 물어볼 수 있습니다.0
1
답변2
다음과 같은 작업을 더 수행하고 싶을 것입니다.
for i in $(cat /tmp/10218.after)
do
grep $(echo ${i} | cut -f1) /tmp/10218.before
done
grep이 실패할 때 좀 더 멋지게 인쇄하고 싶다면 다음과 같이 할 수 있습니다.
for i in $(cat /tmp/10218.after)
do
COUNT=grep -c $(echo ${i} | cut -f1) /tmp/10218.before
if [[ ${COUNT} -eq 0 ]]
then
echo "${i}: Not Found"
else
echo "${i}: Found"
fi
done
답변3
펄을 사용하세요.
#!/usr/bin/perl
use strict;
use warnings;
my %words_to_find;
open ( my $input, "<", "/tmp/10218.after" );
while ( my $line = <$input> )
{
my ( $word ) = ( $line =~ m/\A(\S+)\s/ );
$words_to_find{$word}++;
}
close ( $input );
open ( my $search, "<", "/tmp/10218.before" );
while ( my $line = <$search> )
{
foreach my $word ( key %words_to_find )
{
if ( $line =~ m/$word/ )
{
print $line;
last;
}
}
}
close ( $search );
이와 같은 것이 트릭을 수행해야합니다.
답변4
귀하의 코드가 수행하는 작업은 한 파일의 탭으로 구분된 목록에서 첫 번째 필드를 추출한 다음 두 번째 파일에서 해당 단어를 찾으려고 시도하는 것입니다.
단어 목록을 배열에 저장하지 않음으로써 이를 약간 단순화할 수 있습니다.
cut -f1 /tmp/10218.after | grep -f /dev/stdin /tmp/10218.before
그러면 첫 번째 파일에서 단어가 추출되어 grep
두 번째 파일과 일치하는 데 사용되는 패턴에 직접 전달됩니다.
그러나 여기서는 몇 가지 최적화를 수행할 수 있습니다. 첫째, 단어 목록에 다음 항목만 포함되어 있는지 확인할 수 있습니다.고유한성격:
cut -f1 /tmp/10218.after | sort -u | grep -f /dev/stdin /tmp/10218.before
grep
둘째, 우리는 보장할 수 있습니다문자열 비교정규식 일치 대신:
cut -f1 /tmp/10218.after | sort -u | grep -F -f /dev/stdin /tmp/10218.before
그런 다음 일치하는 부분 문자열을 반환하지 않을 수도 있습니다 grep
(예: bee
in bumblebee
).
cut -f1 /tmp/10218.after | sort -u | grep -wF -f /dev/stdin /tmp/10218.before
또한 다음 단어만 일치하는지 확인할 수도 있습니다.첫 번째고정된 정규식으로 단어를 다시 작성하여(및 drop ) -F
두 번째 파일에서 열을 제거합니다 .
cut -f1 /tmp/10218.after | sort -u | sed 's/^/^/' | grep -w -f /dev/stdin /tmp/10218.before
이 sed
명령은 ^
각 줄의 시작 부분에 삽입되므로 bee
문자열 대신 정규식을 얻습니다 ^bee
.
또는 하나의 awk
프로그램을 사용하여 모든 작업을 수행할 수도 있습니다.
awk -F '\t' 'FNR == NR { words[$1]++; next } words[$1]' /tmp/10218.after /tmp/10218.before
이는 첫 번째 파일의 첫 번째 탭으로 구분된 열을 키로 배열로 읽은 words
다음 두 번째 파일에서 해당 키를 기반으로 하는 단어를 확인합니다. 두 번째 파일의 단어가 키로 나타나면 두 번째 파일의 줄을 인쇄합니다.
출력 순서에 신경 쓰지 않으면 다음을 사용할 수도 있습니다 join
.
join <( cut -f1 /tmp/10218.after | sort -u -b ) <( sort -b /tmp/10218.before )
bash
명령을 작성하는 이 특별한 방법에는 프로세스 대체(예:)를 이해하는 쉘이 필요합니다 <(...)
.
다른 쉘에서는:
cut -f1 /tmp/10218.after | sort -u -b -o keys
sort -b -o data /tmp/10218.before
join keys data