Ich möchte in einer Textdatei einige Select-Anweisungen speichern, die Variablen wie ein Datum enthalten:
$ cat res.txt
select field1, field2 from log and log_time~'"${TODAY}"*'
Ich möchte ein Skript verwenden, das diese Datei analysiert und für jede Anweisung diese ausführt. Natürlich ${TODAY}
wird durch eine Variable ersetzt.
Leider ${TODAY}
wird es nie durch ein Datum ersetzt, wenn ich die Datei lese ...
Gibt es eine Möglichkeit, dies zu erreichen?
AKTUALISIEREN:
Angenommen, ich möchte eine Datei durchlaufen, die einige SQL-Anweisungen enthält, und diese mit psql (postgres) ausführen.
Hier ist die Datei:
$cat sql.res
select path from log where log_host='toto' and log_time~'"${TODAY}"*' and log_msg='POLICY MISSING' and entry_status!='ACK' and path~'^/logs-${cli}/"${THREE_MONTHS_AGO}"_[0-9][0-9][0-9][0-9][0-9][0-9](_[0-9]{1,2}\.|\.)log(ptr|initial_ptr|account_ptr)?\.bz2$';
Jetzt möchte ich in einem Bash-Skript:
$cat script.sh
TODAY=$(date "+%Y-%m-%d")
THREE_MONTHS_AGO=$(date -d "$TODAY -91 days" "+%Y-%m-%d")
THREE_MONTHS_AGO_2=$(date -d "$TODAY -92 days" "+%Y-%m-%d")
ONE_MONTH_AGO=$(date -d "$TODAY -36 days" "+%Y-%m-%d")
ONE_MONTH_AGO_2=$(date -d "$TODAY -37 days" "+%Y-%m-%d")
YESTERDAY=$(date -d "$TODAY -1 day" "+%Y-%m-%d")
while read item; do
psql -P pager=off -t -c "$item" log | sed -e 's|^ *||' -e '/^$/d' > result.txt
done < sql.res
Leider werden die Variablen im Skript nicht verwendet. Ich habe es also mit eval versucht. Das Ergebnis war wie folgt:
$while read item; do
c=$(echo $item | sed "s:':@:g" | sed "s:|:EE:g" | sed "s:(:AA:g" | sed "s:):BB:g" | sed 's:]{:TT:g' | sed 's|\.|OO|g')
b=$(eval echo ${c} 2>&1)
d=$(echo $b | sed "s:@:':g" | sed "s:EE:|:g" | sed "s:AA:(:g" | sed "s:BB:):g" | sed 's:TT:]{:g' | sed 's:OO:\\\.:g' )
echo "-> $b"
done < sql.res
Aber ich habe einige Probleme mit
\.
Antwort1
Sie können die Variablenzeichenfolge einfach durch den Wert ersetzen:
sed -e "s/\${TODAY}/$TODAY/g" res.txt
Aber:
- Stellen Sie unbedingt sicher, dass Sie die Variable durch eine zuverlässige (wie in, erstellt durch die bereitgestellte Datenbank oder Teil einer beliebten Programmiersprachen-API,nichtetwas selbstgebrautes)Fluchtmechanismus.
- Sie müssen außerdem alle Zeichen escapenspeziell für
sed
(und Sie können nicht einfach vor jedem Zeichen einen Backslash hinzufügen). - Sie verwenden zwei Anführungszeichenebenen, was wahrscheinlich nicht beabsichtigt war.
- Bitte verwenden Sie hierfür eine bessere Sprache als Bash. Es ist für diese Art von Dingen schrecklich, weil all das Anführungszeichen und Escapezeichen es kompliziert und machtWirklichSonderfälle können leicht übersehen werden. Python, Ruby und sogar PHP können mit solchen Dingen viel besser umgehen als Bash.