Portál AbcLinuxu, 12. května 2025 05:31

Dotaz: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru

30.12.2020 18:49 Nie som robot
BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Přečteno: 559×
Odpovědět | Admin
Zdravím, potrebujem hromadne odstranit pomlčku (- aj _) z názvu súboru - rekurzívne a hromadne. Vyskytujú sa mi v tisíckach adresároch takéto nezmysly v názvoch súborov aj adresárov: nazov_suboru-.avi nazov_suboru_,avi NAZOV_ADRESARU- alebo NAZOV_ADRESARU_. Najlepšie v BASHi... Ďakujem.
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

30.12.2020 20:37 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
find .  -type d -print | ( while read oldname; do newname=`echo $oldname | sed s/[-_]//g`; mv "$oldname" "$newname"; done)
find .  -type f -print | ( while read oldname; do newname=`echo $oldname | sed s/[-_]//g`; mv "$oldname" "$newname"; done)
Pre istotu navrhujem miesto "mv" vyskúšať "echo mv".
30.12.2020 21:17 z_sk | skóre: 34 | blog: analyzy
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
pri type d, daj mv s parametrom -R
debian.plus@protonmail.com
k3dAR avatar 31.12.2020 00:17 k3dAR | skóre: 63
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
ne, si pletes "mv" s "cp" ;-)
porad nemam telo, ale uz mam hlavu... nobody
31.12.2020 08:30 Peter Golis | skóre: 64 | blog: Bežné záležitosti | Bratislava
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
To je úplne jedno, ajtak bude po takto jednoduchom premenovaní veľmi neočakávaná úspora miesta.

Názvy spracovaniu nevadia. Spracováva sa obsah, a tomu sa duplikáty odstraňujú inak...
1.1.2021 03:44 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
find .  -type d -print | ( while read oldname; do newname=`echo $oldname | sed s/[-_]//g`; mv "$oldname" "$newname"; done)
find .  -type f -print | ( while read oldname; do newname=`echo $oldname | sed s/[-_]//g`; mv "$oldname" "$newname"; done)

Vždyť to^^^ vůbec nefunguje. Ani trochu. Příklad:

mkdir -p /tmp/blah/a-b/c-d
cd /tmp/blah
touch a-b/c-d/e-f

Tak. A teď to zkusme spustit:

mv: '.' a './.' jsou jeden a tentýž soubor
mv: nelze získat informace o './a-b/c-d': Adresář nebo soubor neexistuje
mv: nelze přesunout './ab/c-d/e-f' do './ab/cd/ef': Adresář nebo soubor neexistuje

(I kdyby to fungovalo, posteskl bych si pořád ještě nad

  1. zbytečným spouštěním procesu mv, když nedojde ke změně názvu, včetně adresáře ./,
  2. zbytečným subshellem za | a
  3. zbytečným spouštěním procesu sed (a subshellu) na něco, co umí Bash (${name//@(_|-)}),
jenže ono to nefunguje, takže si jakože nestýskám. :-D)

Tohle funguje, přinejmenším na výše uvedeném příkladu…

1.1.2021 12:16 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Na to aby som poskytol perfektné riešenie som primálo platený ;-)

Pomôže zaradiť tac?
find .  -type d -print | tac | ( while read oldname; do newname=`echo $oldname | sed s/[-_]//g`; echo mv "$oldname" "$newname"; done)
mv ./a-b/c-d ./ab/cd
mv ./a-b ./ab
mv . .
1.1.2021 22:27 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru

Stačil by -depth, jak jsem psal níže.

(Řešení nemusí být perfektní, nicméně paměťové nároky by neměly záviset lineárně na počtu nalezených cest (tac) a neměly by se zbytečně spouštět procesy sed a mv na každou cestu; mv není potřeba všude a sed není potřeba vůbec.)

30.12.2020 20:53 Peter Golis | skóre: 64 | blog: Bežné záležitosti | Bratislava
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
To je domáca úloha "ako v Bashi vytvoriť alternatívu ku programu detox"?
30.12.2020 21:04 Nie som robot
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Detox to neodstrani, ujo ...
30.12.2020 21:23 Peter Golis | skóre: 64 | blog: Bežné záležitosti | Bratislava
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Holt tak už dali parameter --remove-trailing (Removes _ and - after .'s in filenames) medzi zastaralé možnosti, študentík. Ale v manuálovej stránke to zdôvodnili, aj s alternatívou ako toho znova dosiahnuť.
1.1.2021 03:12 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
find -depth | while read name; do
  base="${name##*/}"
  new_base="${base//@(_|-)}"
  if [[ "${new_base}" != "${base}" ]]; then
    echo mv "${name}" "${name%/*}/${new_base}"
  fi
done
  1. Pokud výstup výše uvedeného odpovídá představám, stačí odstranit echo a spustit to naostro.
  2. Vřele doporučuji udělat napřed snapshot celého subvolume, ve kterém je adresářový strom. Snapshot je dílem milisekund a v případě chyb je k nezaplacení.
  3. Je třeba mít zapnutý extglob. (Dnes už bývá implicitně zapnutý.)
2.1.2021 02:01 Nie som robot
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Bohuzial ziaden vystup to nedava...
Jendа avatar 2.1.2021 08:27 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
No tak si tam asi budeš muset napsat debugovací echo, odstranit dočasně tu podmínku, a/nebo to spustit s bash -x.
3.1.2021 11:16 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru

No to je ale smůla. :-D (Fakt nevím, co jiného se na tohle dá odpovědět.)

Pokud jsi si jistý, že (1) máš zapnutý extglob (shopt -s extglob) a (2) jsi ve správném adresáři, asi to budeš muset nějak debuggovat. Co třeba

  1. zkusit spustit samotný find -depth, co to vypíše?
  2. vypsat si v cyklu proměnné base a new_base, jestli mají očekávanou hodnotu a jestli se liší, kdy se mají lišit?
k3dAR avatar 3.1.2021 17:22 k3dAR | skóre: 63
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
diky, netusil sem ze lze v ramci bash manipulaci promene provadet vice odstraneni najednou :-)

nejde nahodou delat i vice ruznych zamen najednou? teda ne neco=${neco//nahrad/zato}; neco=${neco//nahradjeste/zatohle}
porad nemam telo, ale uz mam hlavu... nobody
3.1.2021 18:57 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
Bohužel ne. Jedině kdyby "zato" == "zatohle", to by potom šlo:
something='nahraď nahraďještě nahraď'
echo "${something//nahraď?(ještě)/hovno}"
Bohužel jsem nenašel v dokumentaci ani takovou věc jako možnost vložit matchovaný řetězec (nebo jeho část) do náhrady, jak to umí třeba programy pracující s regexpy (sed). Nedivil bych se, kdyby to Bash už někde ve zdrojáku měl, zatímco manuálová stránka o tom ještě mlčí.

(Dost dlouho například nebylo zdokumentované „vektorové“ nahrazování u polí, typu…
names=({a,b,c,d}.txt)
echo "${names[@]}"
echo "${names[@]/%.txt/.sql}"
…, i když už notnou dobu fungovalo. Teď už to v manuálové stránce je.)
k3dAR avatar 3.1.2021 20:41 k3dAR | skóre: 63
Rozbalit Rozbalit vše Re: BASH: Potrebujem hromadne odstranit pomlčku z názvu súboru
jasne :-) zvolil sem blbej priklad kdy druhe nahrazeni obsahuje string prvniho :-) slo mi opravdu o 2 rozdilne nejen nahrazovane ale i nahrazujici, ne vse za hovno :-) skoda, ale i tak casto sem v skriptech pro multiodstraneni radeji pouzil sed nez nekolikrat prepisovat promenou pres single manipulaci, takze aspon to ted vim ze muzu a jeste jednou diky :)
porad nemam telo, ale uz mam hlavu... nobody

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.