Ich habe eine Folge von Suchmustern in einem Bash-Array ( ptrn
) gespeichert, die ich an einen Befehl übergeben möchte grep
. Wie kann ich das tun?
ptrn=("FN" "DS")
for fl in "$@"; do # loop through number of files
if [[ -f "$fl" ]]; then
printf '\n%s%s%s\n\n' "$mgn" "==> $flnm <==" "$rst"
grep --color "$ptrn" "$flnm"
fi
done
Antwort1
grep
Wie wäre es, die Muster über eine Unter-Shell weiterzugeben , zB:
grep -f <(printf "%s\n" "${ptrn[@]}") FILE...
Antwort2
Zwei Optionen:
Standardkonforme Vorgehensweise: Verbinde die Muster mit einer neuen Zeile und gib sie als einzelnes Argument an:
grep -e "$(printf "%s\n" "${ptrn[@]}")" ...
(Diese Funktion wird angegeben durchder POSIX-Standard: "DerMusterlisteDer Wert muss aus einem oder mehreren durch <newline>-Zeichen getrennten Mustern bestehen ...")
Nicht standardmäßige, aber dennoch sichere Methode: Wenn Sie eine Shell mit Arrays verwenden, wie z. B. Bash, erstellen Sie ein Array von Argumenten für
grep
:args=() for p in "${ptrn[@]}" do args+=(-e "$p") done grep "${args[@]}" ...
Dies ist sicher vor Feldaufspaltung und Globbing und ist im Allgemeinenwie Befehlszeilen aus Variablen aufgebaut werden sollten.
Antwort3
Wenn Ihre als Array-Elemente gespeicherten Muster/Wörter garantiert keine Leerzeichen oder nicht maskierte Shell-Sonderzeichen enthalten, können Sie bash
die Parametererweiterung von verwenden, um die Array-Elemente grep
als separate einzelne Muster zu übergeben, z. B. -e FN -e DS ...
so:
ptrn=("FN" "DS")
# Prepend "-e" to each array element
ptrn2="${ptrn[@]/#/-e }"
# Don't quote "$ptrn2" or it will be passed as a single token and wouldn't work.
grep --color $ptrn2 file
Oder wenn sie nicht maskierte Shell-Sonderzeichen enthalten, können Sie die regulären Ausdrücke um |
( herum aufbauen.oder) (Aufteilung auch auf allen Feldern, aber kein Fehler) und verwenden Sie es mit etwas wie:
ptrn=("FN" "DS")
# Translate spaces " " single or multiple including spaces between words in a single array element into "|".
ptrn2="$(echo ${ptrn[@]} | tr " " "|")"
# -E enables extended regular expressions ... needed for this to work.
grep --color -E "$ptrn2" file
Oder um die exakten Leerzeichen innerhalb jedes regulären Ausdrucksmusters beizubehalten, übergeben Sie jedes Array-Element als einzelnes Token und erstellen Sie daraus einen erweiterten regulären Ausdruck mithilfe von |
(logisch oder), können Sie Folgendes tun:
ptrn=("FN" "DS")
# Append "|" to each array element.
ptrn2="$(printf '%s|' "${ptrn[@]}")"
# Delete the last character i.e. the extra "|".
ptrn2="${ptrn2::-1}"
# -E enables extended regular expressions ... needed for this to work.
grep --color -E "$ptrn2" file