Ich habe eine Datei, die Verzeichnisnamen enthält:
my_list.txt
::
/tmp
/var/tmp
Ich möchte Bash einchecken, bevor ich einen Verzeichnisnamen hinzufüge, wenn dieser Name bereits in der Datei vorhanden ist.
Ich habe eine Datei, die Verzeichnisnamen enthält:
my_list.txt
::
/tmp
/var/tmp
Ich möchte Bash einchecken, bevor ich einen Verzeichnisnamen hinzufüge, wenn dieser Name bereits in der Datei vorhanden ist.
Antworten:
grep -Fxq "$FILENAME" my_list.txt
Der Exit-Status ist 0 (true), wenn der Name gefunden wurde, 1 (false), wenn nicht, also:
if grep -Fxq "$FILENAME" my_list.txt
then
# code if found
else
# code if not found
fi
Hier sind die relevanten Abschnitte der Manpage fürgrep
:
grep [options] PATTERN [FILE...]
-F
,--fixed-strings
Interpretieren Sie PATTERN als eine Liste fester Zeichenfolgen, die durch Zeilenumbrüche getrennt sind und mit denen alle übereinstimmen sollen.
-x
,--line-regexp
Wählen Sie nur die Übereinstimmungen aus, die genau mit der gesamten Zeile übereinstimmen.
-q
,--quiet
,--silent
Ruhig; Schreiben Sie nichts in die Standardausgabe. Beenden Sie das Programm sofort mit dem Status Null, wenn eine Übereinstimmung gefunden wird, auch wenn ein Fehler festgestellt wurde. Siehe auch die Option
-s
oder--no-messages
.
Wie in den Kommentaren zu Recht ausgeführt, behandelt der obige Ansatz Fehlerfälle stillschweigend so, als ob die Zeichenfolge gefunden worden wäre. Wenn Sie Fehler auf andere Weise behandeln möchten, müssen Sie die -q
Option weglassen und Fehler anhand des Beendigungsstatus erkennen:
Normalerweise ist der Exit-Status 0, wenn ausgewählte Zeilen gefunden werden, andernfalls 1. Der Exit-Status ist jedoch 2, wenn ein Fehler aufgetreten ist, es sei denn, die Option
-q
oder--quiet
oder--silent
wird verwendet und eine ausgewählte Zeile wird gefunden. Beachten Sie jedoch, dass POSIX nur Mandate, für Programme wiegrep
,cmp
unddiff
, dass der Exit - Status im Fehlerfall größer als 1 ist ; Aus Gründen der Portabilität ist es daher ratsam, eine Logik zu verwenden, die diese allgemeine Bedingung prüft, anstatt strikt mit 2 gleich zu sein.
Um die normale Ausgabe von zu unterdrücken grep
, können Sie sie umleiten /dev/null
. Beachten Sie, dass der Standardfehler ungerichtet bleibt, sodass alle grep
möglicherweise ausgegebenen Fehlermeldungen auf der Konsole angezeigt werden, wie Sie es wahrscheinlich möchten.
Um die drei Fälle zu behandeln, können wir eine case
Anweisung verwenden:
case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in
0)
# code if found
;;
1)
# code if not found
;;
*)
# code if an error occurred
;;
esac
$?
. Sie können auch den Befehl grep neben der if
Anweisung verwenden (wie in der aktualisierten Antwort gezeigt).
grep -Fqx "$FILENAME"
Regex-Zeichen im variablen Inhalt verwenden und müssen sich keine Gedanken darüber machen, und Sie müssen sie nicht in der Suchzeichenfolge verwenden.
-q / --silent
es gebraucht wird? Es sagt fälschlicherweise "alles gut", um zu schlagen, selbst wenn ein Fehler auftritt. Wenn ich das richtig verstanden habe. Scheint ein fehlerhaftes Konzept für diesen Fall.
In Bezug auf die folgende Lösung:
grep -Fxq "$FILENAME" my_list.txt
Falls Sie sich fragen (wie ich), was -Fxq
im Klartext bedeutet:
F
: Beeinflusst die Interpretation von PATTERN (feste Zeichenfolge anstelle eines regulären Ausdrucks)x
: Ganze Linie abgleichenq
: Shhhhh ... minimaler DruckAus der Man-Datei:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.
(-F is specified by POSIX.)
-x, --line-regexp
Select only those matches that exactly match the whole line. (-x is specified by POSIX.)
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero status if any match is
found, even if an error was detected. Also see the -s or --no-messages option. (-q is specified by
POSIX.)
Drei Methoden in meinem Kopf:
1) Kurztest für einen Namen in einem Pfad (ich bin nicht sicher, ob dies Ihr Fall sein könnte)
ls -a "path" | grep "name"
2) Kurztest für eine Zeichenfolge in einer Datei
grep -R "string" "filepath"
3) Längeres Bash-Skript mit Regex:
#!/bin/bash
declare file="content.txt"
declare regex="\s+string\s+"
declare file_content=$( cat "${file}" )
if [[ " $file_content " =~ $regex ]] # please note the space before and after the file content
then
echo "found"
else
echo "not found"
fi
exit
Dies sollte schneller sein, wenn Sie mehrere Zeichenfolgen für einen Dateiinhalt mithilfe einer Schleife testen müssen , z. B. um den regulären Ausdruck an einem beliebigen Cicle zu ändern.
Einfacherer Weg:
if grep "$filename" my_list.txt > /dev/null
then
... found
else
... not found
fi
Tipp: Senden Sie an, /dev/null
wenn Sie den Beendigungsstatus des Befehls, jedoch keine Ausgaben wünschen.
-q
die gleiche wie --quiet
:)
-q
hier auch der besten Antwort zu und ist Vierter. keine Gerechtigkeit in dieser Welt.
Der einfachste und einfachste Weg wäre:
isInFile=$(cat file.txt | grep -c "string")
if [ $isInFile -eq 0 ]; then
#string not contained in file
else
#string is in file at least once
fi
grep -c gibt zurück, wie oft die Zeichenfolge in der Datei vorkommt.
Wenn ich Ihre Frage richtig verstanden habe, sollte dies das tun, was Sie brauchen.
In einer Zeile :check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt
grep -q
direkt von if
Thomas aus verwenden und aufrufen, wie es Thomas in seiner Antwort tut. Außerdem wurde nicht geprüft, ob das Verzeichnis vorhanden ist, bevor es zur Liste hinzugefügt wurde (es könnte sich schließlich um eine Liste gelöschter Verzeichnisse handeln).
grep -E "(string)" /path/to/file || echo "no match found"
Mit der Option -E verwendet grep reguläre Ausdrücke
Die Lösung von @ Thomas hat aus irgendeinem Grund bei mir nicht funktioniert, aber ich hatte eine längere Zeichenfolge mit Sonderzeichen und Leerzeichen, sodass ich die Parameter wie folgt geändert habe:
if grep -Fxq 'string you want to find' "/path/to/file"; then
echo "Found"
else
echo "Not found"
fi
Hoffe es hilft jemandem
Eine grep-freie Lösung funktioniert für mich:
MY_LIST=$( cat /path/to/my_list.txt )
if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
echo "It's there!"
else
echo "its not there"
fi
basierend auf: https://stackoverflow.com/a/229606/3306354
grep -q
In der akzeptierten Antwort beschrieben ist der effizienteste Ansatz.
grep -Fxq "String to be found" | ls -a
ls
Standardeingaben akzeptiert werden?