Ich habe ein Verzeichnis mit mehreren Dateien, von denen einige Leerzeichen in ihren Namen haben:
Test workspace/
Another directory/
file1.ext
file2.ext
demo 2012-03-23.odp
Ich benutze den $(wildcard)
Befehl von GNU für dieses Verzeichnis und iteriere dann über das Ergebnis, indem $(foreach)
ich alles ausdrucke. Hier ist der Code:
FOO := $(wildcard *)
$(info FOO = $(FOO))
$(foreach PLACE,$(FOO),$(info PLACE = $(PLACE)))
Folgendes würde ich erwarten, wenn es ausgedruckt wird:
Test workspace
Another directory
file1.ext
file2.ext
demo 2012-03-23.odp
Folgendes würde ich tatsächlich bekommen:
Test
workspace
Another
directory
file1.ext
file2.ext
demo
2012-03-23.odp
Letzteres nützt mir offensichtlich nichts. In der Dokumentation zu $(wildcard)
Flat-Out heißt es, dass eine "durch Leerzeichen getrennte Liste von Namen" zurückgegeben wird, die damit verbundenen großen Probleme jedoch nicht vollständig berücksichtigt werden. Auch die Dokumentation für $(foreach)
.
Kann man das umgehen? Wenn das so ist, wie? Das Umbenennen jeder Datei und jedes Verzeichnisses zum Entfernen der Leerzeichen ist keine Option.
$?
und$@
. Wenn Sie interessiert sind, sehen Sie meine Antwort unten. und Louis, ist falsch, es funktioniert. Fühlen Sie sich frei, es selbst zu testenGNU Make funktioniert sehr schlecht mit durch Leerzeichen getrennten Dateinamen.
Leerzeichen werden überall als Trennzeichen in der Wortliste verwendet.
Dieser Blog-Beitrag fasst die Situation gut zusammen, aber WARNUNG: Er verwendet fälschlicherweise \\ anstelle von \
target: some\ file some\ other\ file some\ file some\ other\ file: echo done
Sie können auch Variablen verwenden, damit dies auch funktioniert
VAR := some\ file some\ other\ file target: $(VAR) $(VAR): echo done
Nur die
wildcard
Funktion erkennt das Entkommen, sodass Sie ohne große Schmerzen nichts Besonderes tun können.Vergessen Sie jedoch nicht, dass Ihre Shell auch Leerzeichen als Trennzeichen verwendet .
Wenn ich das ändern wollte ,
echo done
umtouch $@
, würde ich slash hinzufügen , um es für meine Shell zu entkommen.VAR := some\ file target: $(VAR) $(VAR): touch $(subst \,\\,$@)
oder verwenden Sie eher Anführungszeichen
VAR := some\ file some\ other\ file target: $(VAR) $(VAR): touch '$@'
Wenn Sie am Ende viel Schmerz vermeiden möchten, sowohl in GNU make als auch in Ihrer Shell, setzen Sie keine Leerzeichen in Ihre Dateinamen. Wenn Sie dies tun, werden hoffentlich die begrenzten Funktionen von Make ausreichen.
quelle
$(shell ...)
erste Manipulationen durchführen.Diese Methode ermöglicht auch die Verwendung von aufgelisteten Dateinamen wie
$?
und Benutzervariablen, die Listen von Dateien sind.Der beste Weg, mit Leerzeichen in Make umzugehen, besteht darin, andere Zeichen durch Leerzeichen zu ersetzen.
s+ = $(subst \ ,+,$1) +s = $(subst +,\ ,$1) $(call s+,foo bar): $(call s+,bar baz) $(call s+,bar\ baz2) # Will also shows list of dependencies with spaces. @echo Making $(call +s,$@) from $(call +s,$?) $(call s+,bar\ baz): @echo Making $(call +s,$@) $(call s+,bar\ baz2): @echo Making $(call +s,$@)
Ausgänge
Sie können dann Listen mit Dateinamen mit allen GNU Make-Funktionen sicher bearbeiten. Entfernen Sie unbedingt die +, bevor Sie diese Namen in einer Regel verwenden.
SRCS := a\ b.c c\ d.c e\ f.c SRCS := $(call s+,$(SRCS)) # Can manipulate list with substituted spaces OBJS := $(SRCS:.c=.o) # Rule that has object files as dependencies. exampleRule:$(call +s,$(OBJS)) # You can now use the list of OBJS (spaces are converted back). @echo Object files: $(call +s,$(OBJS)) a\ b.o: # a b.o rule commands go here... @echo in rule: a b.o c\ d.o: e\ f.o:
Ausgänge
in rule: a b.o Object files: a b.o c d.o e f.o
Diese Informationen stammen alle aus dem Blog , den alle anderen gepostet haben.
Die meisten Leute scheinen zu empfehlen, keine Leerzeichen in Pfaden oder Windows 8.3-Pfade zu verwenden. Wenn Sie jedoch Leerzeichen verwenden müssen, funktioniert das Escape-Leerzeichen und das Ersetzen.
quelle
+
darin haben?Wenn Sie bereit sind, sich ein bisschen mehr auf Ihre Shell zu verlassen, erhalten Sie eine Liste, die Namen mit Leerzeichen enthalten kann:
$(shell find | sed 's: :\\ :g')
quelle
Die ursprüngliche Frage besagte, dass "Umbenennen keine Option ist", doch viele Kommentatoren haben darauf hingewiesen, dass das Umbenennen so ziemlich die einzige Möglichkeit ist, wie Make mit Leerzeichen umgehen kann. Ich schlage einen Mittelweg vor: Verwenden Sie Make, um die Dateien vorübergehend umzubenennen und sie dann wieder umzubenennen. Dies gibt Ihnen die ganze Macht von Make mit impliziten Regeln und anderen Vorteilen, bringt aber Ihr Dateinamenschema nicht durcheinander.
# Make cannot handle spaces in filenames, so temporarily rename them nospaces: rename -v 's/ /%20/g' *\ * # After Make is done, rename files back to having spaces yesspaces: rename -v 's/%20/ /g' *%20*
Sie können diese Ziele von Hand mit
make nospaces
und aufrufenmake yesspaces
, oder Sie können andere Ziele haben, die von ihnen abhängen. Beispielsweise möchten Sie möglicherweise ein "Push" -Ziel haben, das sicherstellt, dass die Leerzeichen wieder in Dateinamen eingefügt werden, bevor Dateien wieder mit einem Server synchronisiert werden:# Put spaces back in filenames before uploading push: yesspaces git push
[Nebenbei bemerkt: Ich habe versucht , die Antwort , die unter Verwendung vorgeschlagen
+s
unds+
aber es machte meine Make härter und debuggen zu lesen. Ich habe es aufgegeben, als es mich über implizite Regeln beschimpfte, wie :%.wav : %.ogg ; oggdec "$<"
.]quelle