2010-11-10 13 views
6

Mam folder pełen plików graficznych takich jakmasowe zmienianie nazw plików opartych na wyszukiwaniu

  • 1500000704_full.jpg
  • 1500000705_full.jpg
  • 1500000711_full.jpg
  • 1500000712_full.jpg
  • 1500000714_full.jpg
  • 1500000744_full.jpg
  • 1500000745_full.jpg
  • 1500000802_full.jpg
  • 1500000803_full.jpg

muszę zmieniać nazwy plików na podstawie odnośnika z pliku tekstowego, który ma dane, takie jak

  • SH103239 1500000704
  • SH103240 1500000705
  • SH103241 1500000711
  • SH103242 1500000712
  • SH103243 1500000714
  • SH103244 1500000744
  • SH103245 1500000745
  • SH103252 1500000802
  • SH103253 1500000803
  • SH103254 1500000804

Tak, chcę pliki obrazów, aby zostać zmieniona,

  • SH103239_full.jpg
  • SH103240_full.jpg
  • SH103241_full.jpg
  • SH103242_full.jpg
  • SH103243_full.jpg
  • SH103244_full.jpg
  • SH103245_full.jpg
  • SH103252_full.jpg
  • SH103253_full .jpg
  • SH103254_full.jpg

Jak mogę wykonać tę pracę najłatwiej? Czy ktoś może napisać do mnie szybkie polecenie lub skrypt, który może to dla mnie zrobić? Mam wiele tych plików graficznych i ręczna zmiana nie jest możliwa.

Jestem na ubuntu, ale w zależności od narzędzia mogę w razie potrzeby przełączyć się na system Windows. Idealnie chciałbym mieć go w skrypcie basha, aby móc nauczyć się więcej lub prostego perla lub Pythona.

Dzięki

EDIT: musiał zmienić nazwy plików

+0

Czy w pliku odnośnika znajduje się taka sama liczba wpisów, jak w przypadku plików graficznych? –

+0

Istnieje więcej obrazów niż liczba wpisów w pliku – bcrawl

+0

Następnie powtarzanie wpisów jest bardziej wydajne niż wykonywanie iteracji plików. –

Odpowiedz

6

Oto prosty skrypt Pythona 2 do zmiany nazwy.

#!/usr/bin/env python 

import os 

# A dict with keys being the old filenames and values being the new filenames 
mapping = {} 

# Read through the mapping file line-by-line and populate 'mapping' 
with open('mapping.txt') as mapping_file: 
    for line in mapping_file: 
     # Split the line along whitespace 
     # Note: this fails if your filenames have whitespace 
     new_name, old_name = line.split() 
     mapping[old_name] = new_name 

suffix = '_full' 

# List the files in the current directory 
for filename in os.listdir('.'): 
    root, extension = os.path.splitext(filename) 
    if not root.endswith(suffix): 
     # File doesn't end with this suffix; ignore it 
     continue 
    # Strip off the number of characters that make up suffix 
    stripped_root = root[:-len(suffix)] 
    if stripped_root in mapping: 
     os.rename(filename, ''.join(mapping[stripped_root] + suffix + extension)) 

Różne fragmenty skryptu są zakodowane, tak naprawdę nie powinno. Należą do nich nazwa pliku odwzorowania (mapping.txt) i sufiks nazwy pliku (_full). Można je prawdopodobnie przekazać jako argumenty i zinterpretować za pomocą sys.argv.

+0

Witam, czy możesz podać mi kilka szczegółów na temat tego, jak powinienem uruchomić ten skrypt. Kiedy to uruchomię, nic się nie dzieje. Mój plik mapping.txt jest taki sam jak w oryginalnym poście powyżej. Wszelkie wskazówki byłyby świetne. – bcrawl

+0

Przepraszam, nieważne. Uruchomiłem kolejny skrypt. Działa to świetnie. Dzięki. – bcrawl

+0

+1 Ładne i proste. – hughdbrown

1

Przeczytaj w pliku tekstowym, utwórz skrót z aktualną nazwą pliku, więc files['1500000704'] = 'SH103239' i tak dalej. Następnie przejrzyj pliki w bieżącym katalogu, pobierz nową nazwę pliku z hasha i zmień jej nazwę.

+0

Zastępowanie tablicy ciągiem znaków? – tchrist

+0

nie, tylko python. chociaż są one nazywane tablicami asocjacyjnymi ... – muhmuhten

+0

Zobacz odpowiedź @ Wesleya dla kodu podobnego do tego, czego jeszcze nie napisałem. –

5

To będzie pracować dla swojego problemu:

#!/usr/bin/perl 
while (<DATA>) { 
    my($new, $old) = split; 
    rename("$old.jpg", "$new.jpg") 
     || die "can't rename "$old.jpg", "$new.jpg": $!"; 
} 
__END__ 
SH103239 1500000704 
SH103240 1500000705 
SH103241 1500000711 
SH103242 1500000712 
SH103243 1500000714 
SH103244 1500000744 
SH103245 1500000745 
SH103252 1500000802 
SH103253 1500000803 
SH103254 1500000804 

Przełącz do ARGV z DATA czytać wiersze z danego pliku wejściowego.

Normalnie do masy zmienić nazwę operacji, używam czegoś więcej tak:

#!/usr/bin/perl 
# rename script by Larry Wall 
# 
# eg: 
#  rename 's/\.orig$//' *.orig 
#  rename 'y/A-Z/a-z/ unless /^Make/' * 
#  rename '$_ .= ".bad"' *.f 
#  rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i' * 
#  find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/' 

($op = shift) || die "Usage: rename expr [files]\n"; 

chomp(@ARGV = <STDIN>) unless @ARGV; 

for (@ARGV) { 
    $was = $_; 
    eval $op; 
    die if [email protected]; # means eval `failed' 
    rename($was,$_) unless $was eq $_; 
} 

mam bardziej pełni funkcjonalny wersji, ale to powinno wystarczyć.

+0

możemy mieć bardziej w pełni funkcjonalną wersję, którą masz do wykorzystania. może to być przydatne także dla innych użytkowników ... tego, co jeszcze może zrobić twój skrypt. jak mkdir itd. dzięki. – ihightower

+0

@ihightower Patrz [tutaj] (http://training.perl.com/scripts/rename). – tchrist

1
#!/bin/bash 

for FILE in *.jpg; do 
    OLD=${FILE%.*} # Strip off extension. 
    NEW=$(awk -v "OLD=$OLD" '$2==OLD {print $1}' map.txt) 
    mv "$OLD.jpg" "$NEW.jpg" 
done 
2

przepisany od nowa z wykorzystaniem generatorów Wesley'a:

import os, os.path 

with open('mapping.txt') as mapping_file: 
    mapping = dict(line.strip().split() for line in mapping_file) 

rootextiter = ((filename, os.path.splitext(filename)) for filename in os.listdir('.')) 
mappediter = (
    (filename, os.path.join(mapping[root], extension)) 
    for filename, root, extension in rootextiter 
    if root in mapping 
) 
for oldname, newname in mappediter: 
    os.rename(oldname, newname) 
+0

Nasty. Być może nie robiłem Pythona wystarczająco długo (cztery lub pięć lat!), Ale jest to całkowicie nieczytelne dla mnie. –

+0

@ Graeme Perrow: przeczytaj Davida Beazleya na temat generatorów, Zmieniono moje życie. http://www.dabeaz.com/generators/ – hughdbrown

1

Jest to bardzo proste do zrobienia w Bash zakładając, że istnieje wpis w pliku odnośnika do każdego pliku, a każdy plik ma wpis odnośnika.

#!/bin/bash 
while read -r to from 
do 
    if [ -e "${from}_full.jpg" ] 
    then 
     mv "${from}_full.jpg" "${to}_full.jpg" 
    fi 
done < lookupfile.txt 

Jeśli plik odnośnika ma więcej wpisów niż plików, to podejście to może być nieefektywne. Jeśli odwrotność jest prawdziwa, podejście, które iteruje nad plikami, może być nieefektywne. Jeśli jednak liczby są bliskie, może to być najlepsze podejście, ponieważ nie musi on wykonywać żadnych wyszukiwań.

Jeśli wolisz wersję przeglądową, która jest czysta-Bash:

#!/bin/bash 
while read -r to from 
do 
    lookup[from]=$to 
done < lookupfile.txt 

for file in *.jpg 
do 
    base=${file%*_full.jpg} 
    mv "$file" "${lookup[base]}_full.jpg" 
done 
0

Oto zabawna Hack:

paste -d " " lookupfile.txt lookupfile.txt | cut -d " " -f 2,3 | sed "s/\([ ]\|$\)/_full.jpg /g;s/^/mv /" | sh 
2

I zmodyfikowany kod Wesleya pracować dla mojej konkretnej sytuacji. Miałem plik mapowania "sort.txt", który składał się z różnych plików .pdf i liczb, aby wskazać kolejność, w jakiej chcę, w oparciu o dane wyjściowe z manipulacji DOM ze strony internetowej. Chciałem połączyć wszystkie te oddzielne pliki PDF w jeden plik PDF, ale chciałem zachować tę samą kolejność, w jakiej się znajdują, tak jak na stronie internetowej. Więc chciałem dołączyć numery zgodnie z ich lokalizacją drzewa w menu nawigacyjnym.

1054 spellchecking.pdf 
1055 using-macros-in-the-editor.pdf 
1056 binding-macros-with-keyboard-shortcuts.pdf 
1057 editing-macros.pdf 
1058 etc........ 

Oto kod wymyśliłem:

import os, sys 

# A dict with keys being the old filenames and values being the new filenames 
mapping = {} 

# Read through the mapping file line-by-line and populate 'mapping' 
with open('sort.txt') as mapping_file: 
    for line in mapping_file: 

     # Split the line along whitespace 
     # Note: this fails if your filenames have whitespace 
     new_name, old_name = line.split() 
     mapping[old_name] = new_name 


# List the files in the current directory 
for filename in os.listdir('.'): 
    root, extension = os.path.splitext(filename) 

    #rename, put number first to allow for sorting by name and 
    #then append original filename +e extension 
    if filename in mapping: 
     print "yay" #to make coding fun 
     os.rename(filename, mapping[filename] + filename + extension) 

nie mam sufiks jak _full więc nie trzeba tego kodu. Poza tym, że jest to ten sam kod, nigdy nie dotknąłem pytona, więc było to dla mnie dobre doświadczenie edukacyjne.

0
import os,re,sys 

mapping = <Insert your mapping here> #Dictionary Key value entries (Lookup) 

for k,v in mapping: 
    for f in os.listdir("."): 
     if re.match('1500',f): #Executes code on specific files 
      os.rename(f,f.replace(k,v)) 
Powiązane problemy