Chcę wyszukać wiele ciągów w dwóch plikach. Jeśli w obu plikach zostanie znaleziony jeden ciąg, zrób coś. Jeśli jeden ciąg znajduje się tylko w jednym pliku, zrób inną rzecz.
Moje polecenia są następne:
####This is for the affirmative sentence in both files
if grep -qw "$users" "$file1" && grep -qw "$users" "$file2"; then
####This is for the affirmative sentence in only one file, and negative for the other one
if grep -qw "$users" "$file1" ! grep -qw "$users" "$file2"; then
czy to poprawny sposób na zaprzeczenie i potwierdzenie oświadczeń? pd Używam powłoki KSH.
Z góry dziękuję.
text-processing
awk
grep
ksh
Mareyes
źródło
źródło
Inna opcja:
źródło
Uwaga:
((n++))
to rozszerzenie ksh (obsługiwane również przezzsh
ibash
). Wsh
składni POSIX potrzebujeszn=$((n + 1))
zamiast tego.źródło
n=$((n++))
nigdy się nie zmienią wartość n, ponieważn++
jest po inkrementacji: zwraca aktualną wartość n, wtedy przyrosty n; następnie ustaw zmienną na zwróconą wartość, która była oryginalnym n.local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") )
, i użyjcase "${#matches[@]" in
. @glenn: ten pomysł dotyczy również twojej odpowiedzi, aby uniknąć wielokrotnego wywoływaniagrep
. Pipingowanie gogrep -l | wc -l
również działałoby.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.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 . Bashvar=( array elements )
nie ma sposobu używania\0
ogranicznika zamiast\n
. Możemapfile
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ątkowymgrep
awc
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.
$matches
jest skrótem${matches[0]}
od pierwszego elementu tablicy.źródło
-z
, nie-0
, ups. Tak, to spowodowałoby, że grep wypisałby nazwy plików rozdzielone przez,\0
tak jak już wspomniałem w odpowiedzi, ale jak możesz dostać bash, aby to przeanalizować? Nie możesz ustawiaćIFS=$'\0'
, ani robić nic innego zfind -print0
wyjściem stylu bezpośrednio za pomocą bash.grep
.mapfile -d $'\0'
trochę działa, ale zastępuje nowe wiersze spacjami (nie próbowałem poprawiaćIFS
).