Jeśli twoje nazwy plików nie zawierają nowych linii, możesz uniknąć wielokrotnych wywołań grep
, drukując w grep nazwy pasujących plików i policz wyniki.
local IFS=$'\n' # inside a function. Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )
Liczba dopasowań to "${#matches[@]}"
.
Może być tutaj sposób na użycie grep --null -lw
, ale nie jestem pewien, jak przeanalizować dane wyjściowe . Bash var=( array elements )
nie ma sposobu używania \0
ogranicznika zamiast \n
. Może mapfile
wbudowane bash może to zrobić? Ale prawdopodobnie nie, ponieważ określasz separator za pomocą -d string
.
Możesz count=$(grep -l | wc -l)
, ale wtedy masz dwa procesy zewnętrzne, więc równie dobrze możesz po prostu uruchomić grep
dwa pliki osobno. (Różnica między narzutem początkowym grep
a wc
początkowym jest niewielka w porównaniu do opcji fork + exec + linker dynamiczny, aby w ogóle uruchomić osobny proces).
Poza wc -l
tym nie dowiesz się, który plik pasuje.
Po przechwyceniu wyników w tablicy może to być już to, czego chcesz, lub jeśli istnieje dokładnie 1 dopasowanie, możesz sprawdzić, czy to było pierwsze wejście, czy nie.
local IFS=$'\n' # inside a function. Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )
# print the matching filenames
[[ -n $matches ]] && printf 'match in %s\n' "${matches[@]}"
# figure out which input position the name came from, if there's exactly 1.
if [[ "${#matches[@]" -eq 1 ]]; then
if [[ $matches == "$file1" ]];then
echo "match in file1"
else
echo "match in file2"
fi
fi
$matches
jest skrótem ${matches[0]}
od pierwszego elementu tablicy.