[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 » 2013-09-27, 08:38

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 » 2013-09-27, 11:44

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: 1265
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 12:45

-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 » 2013-09-27, 12:49

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: 1265
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 13:19

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 » 2013-09-27, 14:02

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

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

Re: bash zamiana znaków tr

Post autor: mina86 » 2013-09-27, 14:02

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 called “mina86” in response to the previous one. :: Tiny Applications

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

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 14:27

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 » 2013-09-27, 16:31

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: 1265
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 16:59

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 » 2013-09-27, 17:11

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: 1265
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 17:42

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 » 2013-09-27, 18:45

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: 1265
Rejestracja: 2009-10-06, 11:58
Lokalizacja: Gdańsk
Kontakt:

Re: bash zamiana znaków tr

Post autor: webster » 2013-09-27, 19:09

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 » 2013-09-30, 11:13

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