Listendateien, die in einem bestimmten Bereich nummeriert sind

28764
milkypostman

Ich habe eine Reihe von Dateien in einem Verzeichnis, das wie folgt nummeriert ist:

file1.txt file2.txt ... file30.txt ... 

Nun möchte ich einen Befehl für einen bestimmten Dateibereich ausführen, sagen wir 18 bis 31.

Bisher habe ich folgende Möglichkeiten genutzt:

drei argumente

command file1[8-9].txt file2[0-9].txt file3[0-1].txt 

Nehmen wir an, ich möchte jede andere Nummer.

Schleife

for i in `jot - 18 31 2`; do echo file$.txt; done | xargs command 

das scheint eine zuverlässigere Schleife zu sein (Leerzeichen funktionieren)

for i in `jot - 18 31 2`; do echo "\"file$.txt\" "; done | xargs command 

Es scheint jedoch, dass es einen einfacheren Weg geben sollte, dies zu tun. Ich denke, die beste Lösung ist, eine bash-Funktion zu erstellen, die den Satz von Dateien an die Befehlszeile zurückgibt. Dann könnte ich so etwas machen,

command `filerange file 18 31` 

Gibt es bessere Wege oder Vorschläge, um dies effizient zu tun?

Ich entschuldige mich im Voraus, wenn ich die gleiche Frage verpasst habe, die an anderer Stelle im Internet oder auf die Frage gestellt wurde superuser.

15
Ich habe meine Frage so aktualisiert, dass sie eine Lösung enthält, die eine for-Schleife verwendet, die Leerzeichen in Dateinamen mit xargs zulässt. Es scheint zu funktionieren, wenn Sie nicht über Bash 4 verfügen. Wenn Sie Bash 4 haben, verwenden Sie definitiv eine Brace-Erweiterung! ** Siehe die ausgewählte Antwort. ** [Shameless Plug zum Upgrade von Snow Leopard Bash] (http://milkbox.net/brain/brace_completion_snow_leopard_upgrading_bash/) milkypostman vor 13 Jahren 0

1 Antwort auf die Frage

23
Dennis Williamson

Versuche dies:

for file in file.txt 

Es wird als "Sequenzausdruck" bezeichnet und ist Teil der Erweiterungsfunktion von Bash . Es funktioniert in Bash 3 und 4.

Die Inkrementierungsfunktion ist neu in Bash 4. Sie haben wahrscheinlich Bash 3.x.

In Bash 4 können Sie Folgendes tun:

$ for i in ; do echo $i; done 1 3 5 

In Bash 3 müssen Sie jedoch Folgendes tun, um dieselben Ergebnisse zu erzielen:

$ for ((i=1; i<=6; i+=2)); do echo $i; done 

Dasselbe Formular um eins erhöht:

$ for ((i=1; i<=6; i++)); do echo $i; done 

Jede der Zahlen kann Variablen oder Ausdrücke sein. In einem Sequenzausdruck müssen die Zahlen jedoch Konstanten sein

Hier ist ein Beispiel, das dieses Formular in Ihren Dateien verwendet:

for ((i=18; i<=31; i++)) do echo "file$.txt" done 

Ein weiteres neues Feature von Sequenzausdrücken in Bash 4 ist die Möglichkeit, führende Nullen einzufügen. Dies ist nützlich, wenn Sie nummerierte Dateien erstellen (und verwenden) möchten, die ordnungsgemäß sortiert werden können.

In Bash 4:

touch file.txt 

erstellt Dateien mit dem Namen "file001.txt" bis "file010.txt". Ihre Namen werden in der erwarteten Reihenfolge sortiert. Ohne die führenden Nullen würde "file10.txt" vor "file1.txt" sortieren.

Um mit den Dateien zu arbeiten, können Sie dieselbe führende Nullsyntax verwenden:

for file in file.txt; do echo "$file"; done 

Wenn Sie in Bash 3 führende Nullen benötigen, müssen Sie den Wert selbst eingeben:

for i in  do printf -v i '%03d' $i  echo "file$.txt" done 

Die printfAnweisung wird den Wert von i mit führenden Nullen voranstellen, so dass die Breite beispielsweise 3 ist ("4" wird "004").

Bearbeiten:

Leerzeichen in Dateinamen unterzubringen ist unkompliziert:

$ touch "space name "" more spaces" $ ls -l sp* -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces $ for f in "space name "" more spaces"; do mv "$f" "$.txt"; done $ ls -l sp* -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt -rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt 
Danke dir! Ich weiß nicht, wo das mein ganzes Leben war. Die einzige Sache, die ich nicht zur Arbeit bekommen kann, ist, dass das Inkrement in der OSX-Version von bash nicht zu funktionieren scheint. dh ich kann nicht dazu bringen, in meiner OSX-Bash zu arbeiten. milkypostman vor 13 Jahren 0
Nun, es liegt daran, dass Snow Leopard (aus irgendeinem Grund) bash 3.1 verwendet. Dies ist ein Softwareproblem. milkypostman vor 13 Jahren 0
@milkypostman: Die Inkrementierungsfunktion und die führenden Nullen sind neu in Bash 4. Sie haben wahrscheinlich Bash 3.x. Wenn Sie das Inkrementfeature benötigen oder Variablen für die Bereichsgrenzen verwenden, verwenden Sie die folgende Form: `for ((i = 1; i <= 10; i + = 2}` (oder `i ++ 'zum Inkrementieren um eins) Die Zahlen können Variablen oder Ausdrücke sein. Um den Wert innerhalb der `for`-Schleife zu verwenden:` echo "file $ .txt". Wenn Sie in Bash 3 führende Nullen benötigen, machen Sie in der for-Schleife Folgendes: `printf -vi '% 03d' $ i ', der den Wert von' i 'mit führenden Nullen voranstellt, so dass die Breite beispielsweise 3 ist (" 4 "wird" 004 "). Dennis Williamson vor 13 Jahren 0
Dennis, gibt es eine Möglichkeit, Ihre Lösung mit dem alternativen Formular zu aktualisieren? Da es sich um einen Kommentar handelt, ist es ein bisschen zu verschleiern, was ich wahrscheinlich bekommen sollte. milkypostman vor 13 Jahren 0
@milkypostman: Siehe meine bearbeitete Antwort. Dennis Williamson vor 13 Jahren 0
Ich würde nur noch einen Kommentar hinzufügen. Die Methoden, die Sie oben mit `echo` angegeben haben, funktionieren, solange Sie keine Leerzeichen in Ihrem Dateinamen haben. An diesem Punkt brechen sie zusammen. Ich hatte dieses Problem in der Vergangenheit, aber ich vermeide um jeden Preis Dateien mit Leerzeichen. Nur ein Wort der Warnung und warum die Klammererweiterung so schön ist. Anstatt mit dem Loop-Mist herumzuschrauben, habe ich eine neue Version von bash unter OSX installiert (wie Sie das tun, wenn andere neugierig sind) (http://milkbox.net/brain/brace_completion_snow_leopard_upgrading_bash/) milkypostman vor 13 Jahren 0
@milkypostman: Es ist wirklich einfach, Leerzeichen in den Schleifen unterzubringen, wie ich sie gezeigt habe. Siehe meine zusätzliche Bearbeitung. Der Schlüssel ist, die Variable zu zitieren. Dennis Williamson vor 13 Jahren 0