Je souhaite rechercher plusieurs chaînes dans deux fichiers. Si une chaîne est trouvée dans les deux fichiers, faites quelque chose. Si une chaîne se trouve dans un seul fichier, faites autre chose.
Mes commandes sont les suivantes:
####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
est-ce une manière correcte de nier et d'affirmer les déclarations? pd J'utilise le shell KSH.
Merci d'avance.
text-processing
awk
grep
ksh
Mareyes
la source
la source
Une autre option:
la source
Remarque:
((n++))
est une extension ksh (également prise en charge parzsh
etbash
). Dans lash
syntaxe POSIX , vous en auriez besoin à lan=$((n + 1))
place.la source
n=$((n++))
ne changera JAMAIS la valeur de n car iln++
est post- incrémenté: il renvoie la valeur actuelle de n, puis incrémente n; puis vous définissez la variable sur la valeur renvoyée qui était le n d'origine.local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") )
, et utilisezcase "${#matches[@]" in
. @glenn: cette idée s'applique également à votre réponse, afin d'éviter de multiples invocations degrep
. La tuyauteriegrep -l | wc -l
fonctionnerait également.Si vos noms de fichiers ne contiennent pas de sauts de ligne, vous pouvez éviter plusieurs invocations
grep
en demandant à grep d'imprimer les noms des fichiers correspondants et de compter les résultats.Le nombre de correspondances est
"${#matches[@]}"
.Il pourrait y avoir un moyen d'utiliser
grep --null -lw
ici, mais je ne sais pas comment analyser la sortie . Bashvar=( array elements )
n'a aucun moyen d'utiliser un\0
délimiteur à la place de\n
. Peut-être que la fonctionmapfile
intégrée de bash peut le faire? Mais probablement pas, car vous spécifiez le délimiteur avec-d string
.Vous pouvez le faire
count=$(grep -l | wc -l)
, mais vous disposez de deux processus externes, vous pouvez donc tout aussi bien exécutergrep
les deux fichiers séparément. (La différence entre les frais générauxgrep
et lewc
démarrage est faible par rapport à fork + exec + truc de l'éditeur de liens dynamique pour démarrer un processus distinct).De plus,
wc -l
vous ne savez pas quel fichier correspond.Avec les résultats capturés dans un tableau, cela pourrait déjà être ce que vous voulez, ou s'il y a exactement 1 correspondance, vous pouvez vérifier s'il s'agissait de la première entrée ou non.
$matches
est un raccourci pour${matches[0]}
, le premier élément du tableau.la source
-z
, non-0
, oups. Oui, cela amènerait grep à imprimer les noms de fichiers séparés par\0
comme je l'ai déjà mentionné dans la réponse, mais comment pouvez-vous obtenir que bash analyse cela? Vous ne pouvez pas définirIFS=$'\0'
ou faire autre chose avec lafind -print0
sortie de style directement avec bash.grep
points à traiter de toute façon.mapfile -d $'\0'
sorte de travaux, mais il remplace les nouvelles lignes par des espaces (je n'ai pas essayé de peaufinerIFS
).