2016-10-08 3 views
0

Ich habe eine Bash Shell-Skript (mit dem Namen testawk zu ersetzen eine Zeile mit einem Muster (1. arg) mit einer oder mehr als einer Zeile (2. arg) und arbeitet auf der Dateinamen in den 3. arg gegeben der Shell-Skript ist unten angegeben:.gawk und grep mit dem gleichen Muster, aber benötigen unterschiedliche Behandlung für Escape-Sequenz

#!/bin/bash 
if grep -s "$1" "$3" > /dev/null; then 
    gawk -v nm2="$2" -v nm1="$1" '{ if ($0 ~ nm1) print nm2;else print $0}' "$3" > "$3".bak 
    mv "$3".bak "$3" 
fi 

wenn ich eine Datei mit dem Namen „aa“ mit folgendem Inhalt:

a; 
b<*c; 

Und wenn ich testawk als laufen:

./testawk "a;" "x<*y;" "aa" 

aa enthält:

x<*y; 
b<*c; 

Aber wenn ich testawk auf original aa Datei erneut ausgeführt als:

./testawk "b<*c;" "x<*y;" "aa" 

aa enthält nun als (unveränderter Inhalt):

a; 
b<*c; 

Weil, grep "b<*c;" "aa" kann das Muster nicht finden. Um grep glücklich zu machen, wenn ich Escape-Sequenzen wie:

grep "b<\*c;" "aa" 

Es könnte und Shows entspricht:

b<*c; 

wenn ich testawk mit der Escape-Sequenz verwenden, wie unten:

./testawk "b<\*c;" "x<*y;" "aa" 

gawk gefällt nicht und beschwert sich als:

gawk: warning: escape sequence `\*' treated as plain `*' 

Und aa bekommt keine geänderte Inhalte wie:

a; 
b<*c; 

Alle Mittel sowohl grep und gawk glücklich zu machen und finden ersetzen b<*c; Bitte vorschlagen, wie b<*c; zu ersetzen.

+1

Erstens, 'awk' tut bereits Mustererkennung, also müssen Sie wirklich beides tun? Wenn Sie dies tun, versuchen Sie '-F' für' grep' zu verwenden, um das Argument als eine feste Zeichenfolge zu behandeln, kein Muster –

+0

auch, kann '-q' Option von' grep' verwenden, statt stdout irgendwo umzuleiten. Es wird sofort beendet, wenn ein Match gefunden wird, also wird es auch schneller ... und ich denke, 'gawk' hat eine Option für Inplace-Editing ... – Sundeep

+0

@EricRenouf nur um Zeit zu sparen, sowohl Grep und Gawk verwendet, wenn die Datei das Muster enthält dann gawk wird Zeile für Zeile gehen, um zu setzen, wie es ist oder ersetzen, wenn Muster –

Antwort

2

Dies sollte das tun, was ich denke, Sie fordern:

if awk -v nm2="$2" -v nm1="$1" 'index($0,nm1){f=1; $0=nm2} 1; END{exit !f}' "$3" > "${3}.bak" 
then 
    mv "${3}.bak" "$3" 
    # do stuff with modified file "$3" 
else 
    rm -f "${3}.bak" 
    # do stuff with unmodified file "$3" 
fi 

keine Notwendigkeit, etwas außer Schrägstriche zu entkommen, und wir können damit anders umgehen, wenn Sie diese haben.

+0

Fein, welche Änderungen müssen vorgenommen werden, wenn ich nur das erste Vorkommen des Musters ändern möchte und den Rest behalten soll? –

+1

Stick '! F &&' an der Vorderseite. –

+0

Bitte zeigen Sie die Funktion –

Verwandte Themen