2017-05-09 5 views
0

In meinem Verzeichnis gibt es einige HTML-Dateien enthält eine solche Zeichenfolge:
Linux-Shell: sed regex arbeiten mit speziellen Zeichen

sceneFilePath: "./video/video/960.mp4", 

Was ich tun muss, ist den Weg über den richtigen Weg zu ersetzen. Also schreibe ich ein Skript, das zu tun:

find ./video -type f -name "*.mp4" -print0 | while IFS= read -r -d '' myfile; do 
    tmp=$(basename "$myfile") #example.mp4 
    tmp="${tmp/.mp4/.html}" 
    # Here I create a file named $tmp according to a template with the command `cp` 
    cp -rf index.html "$tmp" 
    sed -i '' "s#sceneFilePath:.*,#sceneFilePath: \"${myfile}\",#g" "$tmp" 
done 

Aber es funktioniert nicht. Hier

ist ein Beispiel für $myfile:
./video/Bentota & Hikkaduwa/Hotels/River House/River House - Balapitiya.mp4

Es scheint, dass es wegen der $myfile ist, die einige Sonderzeichen enthält, wie , &, -, oder dass es ist, weil die .* kann nicht übereinstimmen ./video/video/960.mp4.

sed -i '' "s#sceneFilePath:.*#sceneFilePath: \"${myfile//&/\\&}\",#" "$tmp" 

Dieses jedes Vorkommen entweicht von & so dass & verliert es eine besondere Bedeutung in Ersatz:

+0

Hat Ihr Dateiname die Endung '.mp4' oder' .html'? – anubhava

+0

@anubhava oh ich habe einen Fehler gemacht. Ich werde die Frage aktualisieren. – Yves

+0

@anubhava Ich verstehe deine Frage nicht. 'sed' arbeitet an der kopierten HTML-Datei. – Yves

Antwort

0

Lets etwas versuchen:

sed -e "s#sceneFilePath:.*,#fooFilePath: \"${myfile}\",#" index.html 

Ergebnisse in

fooFilePath: "./video/Bentota sceneFilePath: "./video/video/960.mp4", Hikkaduwa/Hotels/River House/River House - Balapitiya.mp4",  

So paßt es die sceneFilePath Linie, ersetzt ihn, fügt dann den angepassten Inhalt, fügt dann den Rest des Ersatzes. Warum?

Vom sed manpage

s/regexp/replacement/ 
      Attempt to match regexp against the pattern space. If success‐ 
      ful, replace that portion matched with replacement. The 
      replacement may contain the special character & to refer to that 
      portion of the pattern space which matched, and the special 
      escapes \1 through \9 to refer to the corresponding matching 
      sub-expressions in the regexp. 

So Ihre & ist nicht entgangen und fügt den angepassten scheneFilePath:. *, Ich würde versuchen, es zu entkommen mit so etwas wie

rep=${myfile//&/\\&} 
sed -i "s#sceneFilePath:.*,#sceneFilePath: \"${rep}\",#g" "${tmp}" 
1

Sie sollten Ihren sed Befehl dies ändern. Unescaped & als Ersatz ist Rückreferenz der vollständigen Übereinstimmung im Substitutionsmuster.

1

Nur awk verwenden :

myfile="$myfile" awk -i inplace 'match($0,/(.*sceneFilePath:).*/,a) {$0=a[1] "\"" ENVIRON["myfile"] "\""} 1' "$tmp" 

Das funktioniert für alle Zeichen in $myfile, da es nur eine wörtliche Stringoperation ausführt. Es verwendet GNU awk für den dritten arg, um() und, was noch wichtiger ist, inplace-Bearbeitung.