So benennen Sie splitfile [az] in splitfile [1-26] um

7

Ich versuche , Dateien in Form von Namen umbenennen splitfile[a-z]zu splitfile[1-26].csv, die ich umbenennen will , ist splitfileazu splitfile1.csvund so weiter.
Ich habe den folgenden Befehl ausprobiert:

mv splitfile[a-z] splitfile[1-26].csv 

aber es funktioniert nicht. Bitte helfen Sie mir, während ich es mit for-Schleife versuche.

user149949
quelle
2
Möglicherweise möchten Sie das Auffüllen mit führenden Nullen in Betracht ziehen, z splitfile01.csv. Die Art und Weise Sie vorschlagen, gewöhnliche Sortierung in der Reihenfolge gesetzt werden splitfile1, splitfile10, splitfile11, ... splitfile19, splitfile2, splitfile20, ... das ist oft unbequem. Insbesondere cat splitfile*.csvwerden sie dadurch nicht mehr in der richtigen Reihenfolge wieder kombiniert.
Nate Eldredge

Antworten:

10

Mit new können bashSie die Klammererweiterung des Formulars verwenden {a..z}:

i=1; for f in file{a..z}; do mv "$f.csv" "${f%?}$((i++)).csv"; done
jimmij
quelle
in file[a-z]ist Arbeit auch, aber unsortiert , so kann es ausgetrickst werden von$(echo file[a-z] | sort)
Costas
Was ist mit file*statt file{a..z}? Ich denke, es sollte funktionieren ...
Mohammad
Und bitte beachten Sie, dass do mv "$f.csv"dies do mv "$f"der Frage entsprechen sollte.
Mohammad
@ mohammad.k Es kann nicht sein, file*dass das auch passen file_something_not_a_single_letterwürde. Auch muss es mv "$f.csv"statt mv "$f", weil file{a..z}Übereinstimmungen filea, ohne Suffix sein .csv.
Jimmyij
2
@Costas - Globs werden standardmäßig nach Gebietsschema sortiert.
Mikeserv
7

Wenn Sie das perlDienstprogramm rename(manchmal aufgerufen prename) haben, können Sie es zum Umbenennen Ihrer Dateien verwenden

rename -n 's/([a-z])$/ord($1)-96/e and $_ .= ".csv"' splitfile?

Dies bedeutet, dass der letzte Buchstabe Ihrer Dateinamen übereinstimmt splitfile?, das Zeichen in sein ASCII-Ordnungsäquivalent konvertiert wird (dh a = 97, b = 98, ...), 96 subtrahiert und der übereinstimmende Buchstabe durch das Ergebnis ersetzt wird. Für alle Dateinamen, bei denen diese Ersetzung erfolgreich angewendet wurde, wird die Zeichenfolge ".csv" angehängt.

Der obige Befehl ändert nicht Ihre tatsächlichen Dateien (das ist, was das -nFlag tut), sondern druckt nur das, was es tun würde. Führen Sie es einmal aus, überprüfen Sie die Ausgabe und führen Sie es, wenn es korrekt ist, erneut ohne aus -n.

Roaima
quelle
4

Mit zshbraucht man nicht um eine Schleife zu verwenden, nur eine zmvFunktion:

autoload -U zmv
i=1 zmv -v '(file)[a-z].csv' '$1$((i++)).csv'

Oder wenn nicht alle file[a-z].csvexistieren können:

letters=({a..z})
zmv -v '(file)([a-z]).csv' '$1$letters[(i)$2].csv'
jimmij
quelle
1

Dieses shSkript benennt Dateien korrekt um, auch wenn Dateien in der a-zSequenz fehlen :

#!/bin/sh
for n in $(seq 26)
do
    f=$(printf $(printf 'file\%03o.csv' $((n+96))))
    [ -e $f ] && echo mv $f file$n.csv
done
RobertL
quelle
0

Dies ist eine Möglichkeit, dies mit einer POSIX-Shell zu tun, vorausgesetzt, alle Dateien sind in der folgenden a-zReihenfolge vorhanden:

#!/bin/sh
i=1
for f in file[a-z].csv
do
    echo mv $f file$i.csv
    i=$((i+1))
done
RobertL
quelle
2
nicht genau ... betrachte die Fälle von Übereinstimmungen auf a und c, aber nicht b.
Mikeserv
@mikeserv, ja, bisher perlscheint nur das Skript das zu erklären.
RobertL
0

Eine andere ziemlich tragbare Lösung ...

    eval    set "'' $(dc -e'123[1-ddP32P97<a]salax')"  ### reverse-order lowercase ascii
    while   "${2+shift}" 2>&-                          ### only iterate while we should
    do      for f   in ./*["$1"].ext                   ### glob* is fine - sorting's done
            do      [ "${f%%*\]????}" ] &&             ### *null glob* kind of
            echo    mv "$f" "${f%?.*}${?%${10+?}}$#.${f##*.}"  ### echo doesn't mv much
    done;   done                                       ### $? zero-pads to two decimals

Nachdem ich die setobige Zeile ausgeführt habe, habe ich einen Testsatz für diese Lösung wie ...

    eval '  for A   in  '"$(printf %1.s%s%1.s "$@" "" ";do for a in$@")"';
            do      echo  "$A$a" > "${A}file$a.ext";        done;   done'

Das überspringt iterativ alle zwei Buchstaben für jeweils zwei Buchstaben ... wenn das Sinn macht. Die Ergebnisse waren:

ls -m

bfilec.ext, bfilef.ext, bfilei.ext, bfilel.ext, bfileo.ext, bfiler.ext,
bfileu.ext, bfilex.ext, efilec.ext, efilef.ext, efilei.ext, efilel.ext,
efileo.ext, efiler.ext, efileu.ext, efilex.ext, hfilec.ext, hfilef.ext,
hfilei.ext, hfilel.ext, hfileo.ext, hfiler.ext, hfileu.ext, hfilex.ext,
kfilec.ext, kfilef.ext, kfilei.ext, kfilel.ext, kfileo.ext, kfiler.ext,
kfileu.ext, kfilex.ext, nfilec.ext, nfilef.ext, nfilei.ext, nfilel.ext,
nfileo.ext, nfiler.ext, nfileu.ext, nfilex.ext, qfilec.ext, qfilef.ext,
qfilei.ext, qfilel.ext, qfileo.ext, qfiler.ext, qfileu.ext, qfilex.ext,
tfilec.ext, tfilef.ext, tfilei.ext, tfilel.ext, tfileo.ext, tfiler.ext,
tfileu.ext, tfilex.ext, wfilec.ext, wfilef.ext, wfilei.ext, wfilel.ext,
wfileo.ext, wfiler.ext, wfileu.ext, wfilex.ext, zfilec.ext, zfilef.ext,
zfilei.ext, zfilel.ext, zfileo.ext, zfiler.ext, zfileu.ext, zfilex.ext

Und dann habe ich es getestet ...

while ...; do ...; done | { HOME=/dev/null; paste -d', ' - ~ - ~; }

mv ./bfilex.ext ./bfile24.ext, mv ./efilex.ext ./efile24.ext,
mv ./hfilex.ext ./hfile24.ext, mv ./kfilex.ext ./kfile24.ext,
mv ./nfilex.ext ./nfile24.ext, mv ./qfilex.ext ./qfile24.ext,
mv ./tfilex.ext ./tfile24.ext, mv ./wfilex.ext ./wfile24.ext,
mv ./zfilex.ext ./zfile24.ext, mv ./bfileu.ext ./bfile21.ext,
mv ./efileu.ext ./efile21.ext, mv ./hfileu.ext ./hfile21.ext,
mv ./kfileu.ext ./kfile21.ext, mv ./nfileu.ext ./nfile21.ext,
mv ./qfileu.ext ./qfile21.ext, mv ./tfileu.ext ./tfile21.ext,
mv ./wfileu.ext ./wfile21.ext, mv ./zfileu.ext ./zfile21.ext,
mv ./bfiler.ext ./bfile18.ext, mv ./efiler.ext ./efile18.ext,
mv ./hfiler.ext ./hfile18.ext, mv ./kfiler.ext ./kfile18.ext,
mv ./nfiler.ext ./nfile18.ext, mv ./qfiler.ext ./qfile18.ext,
mv ./tfiler.ext ./tfile18.ext, mv ./wfiler.ext ./wfile18.ext,
mv ./zfiler.ext ./zfile18.ext, mv ./bfileo.ext ./bfile15.ext,
mv ./efileo.ext ./efile15.ext, mv ./hfileo.ext ./hfile15.ext,
mv ./kfileo.ext ./kfile15.ext, mv ./nfileo.ext ./nfile15.ext,
mv ./qfileo.ext ./qfile15.ext, mv ./tfileo.ext ./tfile15.ext,
mv ./wfileo.ext ./wfile15.ext, mv ./zfileo.ext ./zfile15.ext,
mv ./bfilel.ext ./bfile12.ext, mv ./efilel.ext ./efile12.ext,
mv ./hfilel.ext ./hfile12.ext, mv ./kfilel.ext ./kfile12.ext,
mv ./nfilel.ext ./nfile12.ext, mv ./qfilel.ext ./qfile12.ext,
mv ./tfilel.ext ./tfile12.ext, mv ./wfilel.ext ./wfile12.ext,
mv ./zfilel.ext ./zfile12.ext, mv ./bfilei.ext ./bfile09.ext,
mv ./efilei.ext ./efile09.ext, mv ./hfilei.ext ./hfile09.ext,
mv ./kfilei.ext ./kfile09.ext, mv ./nfilei.ext ./nfile09.ext,
mv ./qfilei.ext ./qfile09.ext, mv ./tfilei.ext ./tfile09.ext,
mv ./wfilei.ext ./wfile09.ext, mv ./zfilei.ext ./zfile09.ext,
mv ./bfilef.ext ./bfile06.ext, mv ./efilef.ext ./efile06.ext,
mv ./hfilef.ext ./hfile06.ext, mv ./kfilef.ext ./kfile06.ext,
mv ./nfilef.ext ./nfile06.ext, mv ./qfilef.ext ./qfile06.ext,
mv ./tfilef.ext ./tfile06.ext, mv ./wfilef.ext ./wfile06.ext,
mv ./zfilef.ext ./zfile06.ext, mv ./bfilec.ext ./bfile03.ext,
mv ./efilec.ext ./efile03.ext, mv ./hfilec.ext ./hfile03.ext,
mv ./kfilec.ext ./kfile03.ext, mv ./nfilec.ext ./nfile03.ext,
mv ./qfilec.ext ./qfile03.ext, mv ./tfilec.ext ./tfile03.ext,
mv ./wfilec.ext ./wfile03.ext, mv ./zfilec.ext ./zfile03.ext,
mikeserv
quelle
0

Hier ist ein alternativer Vorschlag, der fehlende Dateien nicht unterstützt, aber ich hatte das Bedürfnis, eine "funktionalere" Lösung auszuprobieren, die mit Tupeln funktioniert:

#!/bin/bash
splitfile_renamer() {
  mv splitfile$1 splitfile$2.csv
}

paste <(echo -en {a..z}"\n") <(seq 26) | while read args
  do splitfile_renamer $args
done

Mit den obigen pasteAnweisungen werden die Argumenttupel (durch Leerzeichen getrennt) erstellt und an eine vorgefertigte Funktion übergeben, die sie dann als nummerierte Argumente aufnimmt.

yoniLavi
quelle