Zeichenmuster am Anfang und Ende von Dateinamen entfernen

Zeichenmuster am Anfang und Ende von Dateinamen entfernen

Ich habe eine Reihe von Dateien, die ich umbenennen möchte. Ihre Dateinamen haben ein bestimmtes Format:

p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j

Vor jedem eindeutigen Dateinamen steht ein Präfix. In diesem Fall beginnt das Präfix mit dem Buchstaben pund hat eine Zahl dahinter, die pum eins erhöht wird. Ein Punkt ( .) trennt das Präfix vom eindeutigen Dateinamen. Nach jedem eindeutigen Dateinamen steht ein Suffix, das mit einem Hashtag ( #) beginnt. Ich möchte die Präfixe bis einschließlich der Punkte entfernen und ich möchte auch die Suffixe entfernen, die bei den Hashtags beginnen und diese einschließen. Ich möchte, dass die resultierenden Dateinamen nur die eindeutigen Dateinamen zwischen den Punkten und den Hashtags sind, wie hier:

uniquenameA
uniquenameB
uniquenameC
uniquenameD
uniquenameE
uniquenameF
uniquenameG
uniquenameH
uniquenameI
uniquenameJ

Ich habe keine Erfahrung mit Skripting. Wenn Sie mir also nicht nur den Code zur Verfügung stellen, sondern mir auch erklären könnten, wie der Code funktioniert, wäre ich Ihnen sehr dankbar.

Antwort1

perlWenn Sie die Version von rename(früher manchmal genannt ) haben prename, können Sie eine reguläre Ausdrucksersetzung anwenden:

rename -n 's/^.*?\.(.*?)#.*/$1/' *

Wenn Sie reguläre Ausdrücke (REs) nicht verstehen, lohnt es sich auf jeden Fall, sie zu lernen.

  • s/xx/yy/- ersetzen xxmityy
  • ^- Übereinstimmung mit einem impliziten Zeilenanfang
  • .*?- eine möglichst kurze Zeichenfolge abgleichen vonnull oder mehr Zeichen von irgendetwasvorbehaltlich des restlichen Mustervergleichs
  • \.- Übereinstimmung mit einem wörtlichen Punkt .(das .Zeichen steht fürirgendetwas, \.ist aber ein wörtlicher Punkt)
  • (... )sucht nach einem Muster innerhalb der Klammern und weist ihm eine Übereinstimmungsnummer von 1 bis 9 zu; später wird darauf verwiesen durch $1(das zweite (... )wäre $2, usw.)
  • #- wörtlicher Charakter
  • .*- das längste Match, dasnull oder mehr Zeichen von irgendetwas(das .istirgendetwasund das *bedeutet _null oder mehr des vorhergehenden Elements)

Entfernen Sie das -n("keine Aktion"), wenn Sie damit zufrieden sindwürdeArbeit. Ersetzen Sie es durch , -vum zu sehen, was tatsächlich passiert, oder lassen Sie es einfach weg, um den stillen Betrieb zu ermöglichen.

Antwort2

Hier ist ein awkSkript, das diese Aufgabe erledigt:

Nur zum Drucken/Debuggen:

awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){print "mv "$0" "m[2] }' input.txt    

Führen Sie die Umbenennung durch:

awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){system("mv "$0" "m[2])}' input.txt    

Eingabe.txt

p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j

Ausgabe

mv p1.uniquenameA#blah_a uniquenameA
mv p2.uniquenameB#blah_b uniquenameB
mv p3.uniquenameC#blah_c uniquenameC
mv p4.uniquenameD#blah_d uniquenameD
mv p5.uniquenameE#blah_e uniquenameE
mv p6.uniquenameF#blah_f uniquenameF
mv p7.uniquenameG#blah_g uniquenameG
mv p8.uniquenameH#blah_h uniquenameH
mv p9.uniquenameI#blah_i uniquenameI
mv p10.uniquenameJ#blah_j uniquenameJ

Antwort3

Hier ist eine Lösung mitsed

for i in *
do
    mv $i $( echo $i | sed 's/p[[:digit:]]*\.\([^#]*\)\#.*/\1/' )
done

sedDas Ziel wird durch die Suche nach einem gefolgt von einer beliebigen Anzahl von Ziffern und einem Punkt erstellt p. Die Zeichen ab dem Punkt bis zum #Zeichen sindfiel einin ein Register, und der gesamte Dateiname wird durch denfiel einFiguren.

verwandte Informationen