[Rozw.] bash zamiana znaków tr

Problemy dotyczące programowania.

Moderatorzy: Moderatorzy, Administratorzy

Miko
Użytkownik
Posty: 13
Rejestracja: 2012-04-03, 09:05

[Rozw.] bash zamiana znaków tr

Post autor: Miko »

Witam mam mały problem, mam dużą ilość plików w moim Slackware które pochodzą z Windowsa i niestety w nazwach zepsuło mi się kodowanie, więc postanowiłem napisać mały skrypt który zmieni mi wszystkie nazwy plików.

Przykładowa nazwa pliku to:
`Ĺ\233liwka i chce zamienić tę nazwę na śliwka

niestety to polecenie nie działa:
tr -s 'Ĺ\\233' 'ś'

Może ktoś mi doradzi co jest źle.
Ostatnio zmieniony 2013-10-04, 11:25 przez Miko, łącznie zmieniany 2 razy.

Awatar użytkownika
elesmod
Użytkownik
Posty: 47
Rejestracja: 2012-08-30, 13:00

Re: bash zamiana znaków tr

Post autor: elesmod »

tr chyba sobie z tym nie poradzi (on raczej zajmuje się zamianą znaków, a nie ciągów znaków).

Może użyj seda.

Na początek zwykły ls w katalogu, w którym znajduje się ten plik, żeby sprawdzić jak zadziała:

Kod: Zaznacz cały

ls | sed -e 's/`Ĺ\\233/ś/g'
Składnia tego, co występuje za opcją -e wygląda tak:
s/ciąg_do_zastąpienia/ciąg_zastępujący/
oczywiście trzeba postawić dodatkowy backslash przy backslashu, aby bash potraktował go jako zwykły znak;
opcja g na końcu oznacza zastąpienie wszystkich ciągów, a nie tylko pierwszego napotkanego.

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

-e nie jest potrzebne. W bash śliwka będzie wyświetlana z podwójnym '\' tak więc potrzebne będzie '\\\\' przed 233 przy ls

Kod: Zaznacz cały

ls |grep 'Ĺ\\\\233'|while read FILE;do FNAME=$(echo "${FILE}"| sed 's/`Ĺ\\233/ś/g');mv "${FILE}" "${FNAME}" ;done
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Miko
Użytkownik
Posty: 13
Rejestracja: 2012-04-03, 09:05

Re: bash zamiana znaków tr

Post autor: Miko »

Poszedłem za Twoją radą i napisałem taki mały skrypt który niestety nie działa...

Kod: Zaznacz cały

for plik in * ;do 
        mv "$plik" "`echo $plik|sed -e 's/Ĺ\\233/ś/g'`"
done

I niestety nie mogę sobie poradzić...

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

Miko, przecież podałem Tobie gotowy skrypt...

n/c
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Miko
Użytkownik
Posty: 13
Rejestracja: 2012-04-03, 09:05

Re: bash zamiana znaków tr

Post autor: Miko »

Tylko że niestety Twój skrypt nie zmienił mi żadnej nazwy

Awatar użytkownika
mina86
Moderator
Posty: 3330
Rejestracja: 2004-06-14, 21:58
Lokalizacja: Linux 5.x x86_64
Kontakt:

Re: bash zamiana znaków tr

Post autor: mina86 »

Jak no moje to to będzie coś w stylu:

Kod: Zaznacz cały

rename $'Ĺ\233' ś *
Przynajmniej na Slackware. Inne dystribucje mogą mięć inne rename i wówczas:

Kod: Zaznacz cały

rename $'s/Ĺ\233/ś/' *
Oczywiście wymaga odpalenia w bashu (z uwagi na $'').

PS. webster “ls | … | while …” jest prawie zawsze niepoprawnym rozwiązaniem. for, tak jak próbował Miko, jest znacznie lepsze.
Zastrzegam sobie prawo nieanalizowania postów pisanych niepoprawną polszczyzną.
Post generated automatically by A.I. system code name ‘mina86’ in response to the previous one.

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

mina86, zawsze piszę z while i wszystko mi hula :) subiektywna opinia o tym co jest lepsze. Jedno i drugie bazuje nie na jednej a na większej ilości komend. rename zamyka się w jednym i może być ok. To czy Zrobisz sobie for i while to jest bez różnicy.

Z komendą rename mi nie hulało więc zrobiłem na pętli.

Ps. Po testowałem Twoją linię mina86 i nie hula.

Miko, Daj wynik ls w tym katalogu. Starałem się stworzyć taki plik o którym mowa touch '`Ĺ\233liwka' i komenda ls zwraca mi `Ĺ\\233liwka
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Awatar użytkownika
elesmod
Użytkownik
Posty: 47
Rejestracja: 2012-08-30, 13:00

Re: bash zamiana znaków tr

Post autor: elesmod »

webster pisze:Starałem się stworzyć taki plik o którym mowa touch '`Ĺ\233liwka' i komenda ls zwraca mi `Ĺ\\233liwka
U mnie to samo zwraca tylko jeden backslash.

Stworzyłem kilka plików w katalogu. Oto lista:

Kod: Zaznacz cały

ls -1

`Ĺ\233liwka
ko`Ĺ\233ciotrup `Ĺ\233wistaka
królewna `Ĺ\233nieżka
(opcja -1 wyświetla każdy plik w osobnej linii, podobnie jak opcja -l, ale bez zbędnych informacji)

Wpisałem wszystkie komendy, które zostały podane w tym wątku i tylko moja poprawnie zamieniła (tj. tylko wyświetliła) nazwy tych plików.
webster, masz rację, że -e jest niepotrzebne, w końcu nie podajemy wielu ciągów do zamiany, tylko jeden.

I teraz:

Kod: Zaznacz cały

ls | sed 's/`Ĺ\\233/ś/g'

śliwka
kościotrup świstaka
królewna śnieżka
Teraz próbuję rozwiązać problem rzeczywistej zamiany nazw tych plików. Następujący skrypt nie działa:

Kod: Zaznacz cały

for STARA in * ; do
        NOWA=`ls "$STARA" | sed 's/`Ĺ\\233/ś/g'`
        mv "$STARA" "$NOWA"
done
Prawdopodobnie przyczyną jest tutaj ten znak apostrofu `, który rozdziela okalające apostrofy. Niestety (nie wiem dlaczego), nie potrafię go zignorować (escape character) przez dodanie backslasha, o tak: \`

Wiecie, jak rozwiązać ten problem?

edycja:

Ok, poczytałem i udało mi się obejść problem. Zamiast tych grawisów (chyba to jest poprawna nazwa tych apostrofów; ang. backtick) użyłem $(). Czyli:

Kod: Zaznacz cały

#/bin/bash

# zamiana.sh
# zamienia starą nazwę pliku zawierającą ciąg `Ĺ\233 na nową, zastępując go literą ś

for STARA in * ; do
        NOWA=$(ls "$STARA" | sed 's/`Ĺ\\233/ś/g')
        mv "$STARA" "$NOWA"
done
Oczywiście skrypt będzie wyrzucał błędy, jeśli nie znajdzie pliku, który ma w nazwie `Ĺ\233. Jednak swoje zadanie wykonuje.

Oto lista:

Kod: Zaznacz cały

ls -1

kościotrup świstaka
królewna śnieżka
zamiana.sh
śliwka
Ostatnio zmieniony 2013-09-27, 17:05 przez elesmod, łącznie zmieniany 1 raz.

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

a Daj tak

Kod: Zaznacz cały

NOWA=$(ls "${STARA}" | sed 's/`Ĺ\\233/ś/g')
echo "${STARA}" "${NOWA}"
mv "${STARA}" "${NOWA}"
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Awatar użytkownika
elesmod
Użytkownik
Posty: 47
Rejestracja: 2012-08-30, 13:00

Re: bash zamiana znaków tr

Post autor: elesmod »

Aj... A ja zacząłem edycję mojego posta przed tym, gdy Ty wrzuciłeś swój. Wykorzystałem tę samą sztuczkę :)

Sprawdziłem, obie wersje działają (przynajmniej u mnie).

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

No to się cieszkam :))

Daj w temacie [Rozw.] i lecimy dalej :)

Pozdr.
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Awatar użytkownika
elesmod
Użytkownik
Posty: 47
Rejestracja: 2012-08-30, 13:00

Re: bash zamiana znaków tr

Post autor: elesmod »

webster pisze:Daj w temacie [Rozw.] i lecimy dalej :)
Poczekaj, daj szansę Mikowi sprawdzić, czy na jego oryginalnych plikach też będzie działać :)

Awatar użytkownika
webster
Użytkownik
Posty: 1269
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster »

eee tam :p :D
††† Chaos Of The Mirror - Valheru †††
††† I ♥ SlackWare RuLeZ †††

Slackware Poland FaceBook

Miko
Użytkownik
Posty: 13
Rejestracja: 2012-04-03, 09:05

Re: bash zamiana znaków tr

Post autor: Miko »

Dzięki wielkie za pomoc, tylko mam jeszcze jedno pytanko dlaczego wyskakuje mi taki komunikat i nie zmienia nazwy ?

Polecenie ls

Kod: Zaznacz cały

zdjecie.szymuĹ\233.JPG*
skrypt

Kod: Zaznacz cały

#!/bin/bash
                NOWA=$(ls "${STARA}" | sed 's/Ĺ\\233/ś/g')
                 echo "${STARA}" "${NOWA}"
                 mv "${STARA}" "${NOWA}"
Po uruchomieniu skryptu wyskakuje mi następujący komunikat:

Kod: Zaznacz cały

ls: nie ma dostępu do : Nie ma takiego pliku ani katalogu
 
mv: nie można wykonać stat na `': Nie ma takiego pliku ani katalogu

ODPOWIEDZ