2016-08-07 16 views
1

Stellen Sie sich einen Ordner namens parent-folder mit den folgenden. Das übergeordnete Element enthält untergeordnete Elemente, und jedes untergeordnete Element enthält eine style.css-Datei. Ich brauche ein Bash-Skript, das jede CSS-Datei in _style.scss umbenennt. Außerdem muss ich jedem Stylesheet @import 'glue1'; voranstellen.Bash Schleife durch Ordner und Datei umbenennen

parent-folder 
    child-folder 
     style.css 
    child-folder 
     style.css 
    child-folder 
     style.css 

Das habe ich zusammengestellt. Ich habe Mühe, dies zu verstehen, weil ich kein Bash-Wissen habe. Ich finde es sehr schwer, Skripte zu schreiben.

for file in */**; do 
    echo "@import 'glue1';"|cat - $file > /tmp/out && mv /tmp/out $file 
    echo ${file/%.css/.scss} 
done; 

Was das Skript, wenn sie von parent-folder genannt wird:

  1. Schleife durch jedes Unterverzeichnis
  2. Prepend @import 'glue1'; zu jeder CSS-Datei durch eine temporäre Datei zu erstellen.
  3. Echo die neue Datei Route .css mit .scss

Meine Frage ist ...

ersetzen out Was ist [diese] ${file/%.css/.scss} Technik genannt und wie kann ich voranstellen, einen _ (Unterstrich) vor der Dateiname?

+0

Lesen Sie die Manpage für 'finden': es ist für diese Art von Aufgaben gedacht. – boardrider

Antwort

1

${file/%.css/.scss} heißt parameter expansion. Sie ersetzen das Suffix .css durch ein .scss Suffix.

mv $file $(dirname $file)/_$(basename ${file/%.css/.scss}) 

Doch dies scheint übertrieben: Sie könnten Ihre Umbenennung unter Verwendung einer Kombination von Parameter Expansion und einige andere Funktionen wie so erreichen. Wenn Sie wissen, alle Ihre Dateien _style.scss umbenannt werden müssen, unabhängig davon, was sie ursprünglich genannt, dann können Sie einfach tun:

mv $file $(dirname $file)/_style.scss 

Einfachere:

In der Tat, wenn Sie Dateien ändern möchten style.css (Ihr aktuelles Skript ändert jede Datei in jedem Unterverzeichnis), und Sie wissen, dass sie alle bereits heißen, dann wäre dies ein einfacherer Weg, der nur durch jedes Unterverzeichnis Ihres aktuellen Verzeichnisses iteriert (statt aller darin enthaltenen Dateien) diese Unterverzeichnisse):

for dir in */; do 
    echo "@import 'glue1';" | cat - "${dir}"style.css > /tmp/out && mv /tmp/out "${dir}"_style.scss 
done 

oder in eine Datei schreiben, dann entfernen Sie das alte (das sieht mir mehr kanonische):

for dir in */; do 
    echo "@import 'glue1';" >"${dir}"_style.scss 
    cat "${dir}"style.scss >>"${dir}"_style.scss 
    rm "${dir}"style.scss 
done 
+0

'$ {dir}' sollte in doppelte Anführungszeichen eingeschlossen werden, um Globbing und Wortteilung zu verhindern. –

+0

Absolut richtig und fest. – leekaiinthesky

0

Sieht aus wie Sie benötigen find und dirname Befehle zum Umbenennen und sed für das Voranstellen der Linie Datei Inhalt:

for i in `find . -name 'style.css'`; do 
    sed -i '1s;^;@import '"'"'glue1'"'"'\;\n;' $i; 
    mv $i "`dirname $i`/_style.scss"; 
done 

Wenn Sie mit Dateinamen arbeiten anders als style.css benötigen, müssen Sie möglicherweise auch basename Befehl, der die Dateinamen nur extrahiert, so dass es somewha ist t gegenüber dirname.

Es gibt auch rename Befehl, der Muster in Dateinamen ersetzt, aber es scheint eine Überkompilierung für Ihren Fall zu sein.