Ich möchte mehrere Zeichenfolgen in zwei Dateien suchen. Wenn in beiden Dateien eine Zeichenfolge gefunden wird, machen Sie etwas. Wenn eine Zeichenfolge nur in einer Datei gefunden wird, machen Sie eine andere Sache.
Meine Befehle sind die nächsten:
####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
Ist es richtig, die Aussagen zu leugnen und zu bestätigen? pd Ich benutze die KSH-Shell.
Danke im Voraus.
text-processing
awk
grep
ksh
Mareyes
quelle
quelle
Andere Option:
quelle
Hinweis:
((n++))
ist eine ksh-Erweiterung (wird auch vonzsh
und unterstütztbash
). In der POSIX-sh
Syntax benötigen Sien=$((n + 1))
stattdessen.quelle
n=$((n++))
niemals den Wert von n wird sich ändern , dan++
ist Post Schritt: den gibt aktuelle Wert von n, dann Schritten n; Dann setzen Sie die Variable auf den zurückgegebenen Wert, der das ursprüngliche n war.local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") )
, und verwenden Siecase "${#matches[@]" in
. @glenn: Diese Idee gilt auch für Ihre Antwort, um mehrfache Aufrufe von zu vermeidengrep
. Piping esgrep -l | wc -l
würde auch funktionieren.Wenn Ihre Dateinamen keine Zeilenumbrüche enthalten, können Sie mehrere Aufrufe von vermeiden,
grep
indem Sie die Namen der übereinstimmenden Dateien von grep drucken lassen und die Ergebnisse zählen.Die Anzahl der Übereinstimmungen beträgt
"${#matches[@]}"
.Möglicherweise gibt es hier eine Möglichkeit
grep --null -lw
, aber ich bin mir nicht sicher, wie ich die Ausgabe analysieren soll . Bashvar=( array elements )
hat keine Möglichkeit,\0
stattdessen ein Trennzeichen zu verwenden\n
. Vielleicht kann Bash'smapfile
Builtin das? Aber wahrscheinlich nicht, weil Sie das Trennzeichen mit angeben-d string
.Sie könnten
count=$(grep -l | wc -l)
, aber dann haben Sie zwei externe Prozesse, so dass Siegrep
die beiden Dateien genauso gut getrennt ausführen können. (Der Unterschied zwischen Startaufwandgrep
undwc
Startaufwand ist im Vergleich zu Fork + Exec + Dynamic Linker gering, um überhaupt einen separaten Prozess zu starten.)Außerdem finden
wc -l
Sie mit nicht heraus, welche Datei übereinstimmt.Wenn die Ergebnisse in einem Array erfasst wurden, ist dies möglicherweise bereits das, was Sie möchten, oder wenn genau 1 Übereinstimmung vorliegt, können Sie überprüfen, ob es sich um die erste Eingabe handelt oder nicht.
$matches
ist eine Abkürzung für${matches[0]}
das erste Array-Element.quelle
-z
, nicht-0
, oops. Ja, das würde grep dazu bringen, die Dateinamen getrennt zu drucken,\0
wie ich bereits in der Antwort erwähnt habe, aber wie können Sie bash dazu bringen, das zu analysieren? Sie können dieIFS=$'\0'
Stilausgabe nichtfind -print0
direkt mit bash festlegen oder im Grunde nichts anderes tun .grep
sowieso nur ein paar gibt, mit denen man sich befassen muss.mapfile -d $'\0'
Art von Arbeiten, aber es ersetzt die Zeilenumbrüche durch Leerzeichen (ich habe nicht versucht, zu optimierenIFS
).