2013-07-19 11 views
5

Mam listę nazw plików w katalogu (/path/to/local). Chciałbym usunąć pewną liczbę znaków ze wszystkich tych nazw plików.Skrypt Bash, aby usunąć "x" ilość znaków na końcu wielu nazw plików w katalogu?

Przykładowe nazwy plików:

iso1111_plane001_00321.moc1 
iso1111_plane002_00321.moc1 
iso2222_plane001_00123.moc1 

W każdym pliku Chciałbym usunąć ostatnie 5 znaków przed rozszerzeniem.

Na przykład:

iso1111_plane001_.moc1 
iso1111_plane002_.moc1 
iso2222_plane001_.moc1 

wierzę, można to zrobić za pomocą sed, ale nie można określić dokładnego kodowania. Coś jak ...

for filename in /path/to/local/*.moc1; do 
    mv $filname $(echo $filename | sed -e 's/.....^//'); 
done 

... ale to nie działa. Przepraszam, jeśli zmasakrowałem opcje sed, nie mam z tym większego doświadczenia.

+0

'^' jest początkiem linii, z definicji nie może istnieć nic przed nim. – Kevin

Odpowiedz

6
mv $filname $(echo $filename | sed -e 's/.....\.moc1$//'); 

lub

echo ${filename%%?????.moc1}.moc1 

%% jest podmiot wewnętrzny bash ...

+0

Dzięki! Druga opcja, którą zaprezentowałeś, działała doskonale w skrypcie basha. – user2600230

+0

sed przykład jest błędny (nie uwzględnia rozszerzenia), ale +1 dla rozwiązania bash –

+0

@glennjackman, w jaki sposób nie uwzględnia rozszerzenia? –

1

Polecenie sed będzie działać dla wszystkich przykładów dałeś.

sed -e 's/\(.*\)_.*\.moc1/\1_.moc1/' 

Jednakże, jeśli po prostu chcesz się specyficznie „usunąć 5 znaków przed ostatnim rozszerzeniem w pliku” polecenie to jest to, co chcesz:

sed -e 's/\(.*\)[0-9a-zA-Z]\{5\}\.\([^.]*\)/\1.\2/' 

można zaimplementować to w skrypcie jak tak :

for filename in /path/to/local/*.moc1; do 

    mv $filename "$(echo $filename | sed -e 's/\(.*\)[0-9a-zA-Z]\{5\}\.\([^.]*\)/\1.\2/')"; 

done 

pierwsze polecenie Wyjaśnienie

Pierwsze sed polecenie działa chwytając wszystkie znaki aż do pierwszego podkreślenia: \(.*\)_

Następnie odrzuca wszystkie znaki aż znajdzie .moc1: .*\.moc1

Wtedy zastępuje tekst, że to wszystko, to chwycił pierwszy znaleziony wewnątrz nawiasu: /\1

i wreszcie dodaje rozszerzenie .moc1 z powrotem na koniec i kończy regex: .moc1/

Drugie polecenie Wyjaśnienie

Drugi sed polecenie działa chwytając wszystkie znaki na początku: \(.*\)

A potem jest on zmuszony do zatrzymania chwytając znaków, dzięki czemu można go wyrzucić pięć znaków, a dokładniej pięć znaków które leżą w granicach 0-9, az, AZ i: [0-9a-zA-Z]\{5\}

Potem przychodzi kropka '.' charakter z okazji ostatniego rozszerzenia: \.

Następnie szuka wszystkich znaków spoza kropki. Gwarantuje to, że jesteśmy chwytając rozszerzenie ostatni: \([^.]*\)

Wreszcie zastępuje cały ten tekst z pierwszych i drugich grup przechwytujących, oddzielone znakiem ., a kończy regex: /\1.\2/

+0

Dzięki za wyjaśnienie! Spróbuję tego. – user2600230

+0

Dzięki za kod do stripowania na podstawie postaci - mimo, że nie było to pytanie OP - to było moje – kris

0

Może praca dla ciebie (GNU sed):

sed -r 's/(.*).{5}\./\1./' file 
Powiązane problemy