Sziasztok!
Szeretném egy mappámban található összes fájlban (és a benne lévő mappákban lévő fájlokban is, stb...) bizonyos szavakat átírni másik szavakra...
pl az alma szót körte szóra.
két kérdés: sed-del hogy lehet egy fájlban kicserélni a dolgoka, és nem új fájlt létrehozni?
(for i in `ls`;do echo $i;done ezzel ki tudom iratni az összes fájlomat...)
Köszi!
- 2505 megtekintés
Hozzászólások
Ha a file-ok és könyvtárak nevében szeretnéd cserélni (az általad felírt ciklusból kiindulva), és nem a tartalmukban, akkor kb így tenném:
for i in $(find /konyvtar/utvonal); do ujnev=$(echo $i | sed -e 's/mit/mire/g'); mv $i $ujnev; done
[szerk:] ha a find paracsot paraméter nélkül adod ki, akkor az aktuális könyvtárat fogja rekurzívan listázni. lsd, man find
---
"A megoldásra kell koncentrálni nem a problémára."
- A hozzászóláshoz be kell jelentkezni
Érzésem szerint (egy) probléma lesz abból, hogy ha egy alkönyvtárt átnevez, utána már az alatt lévő fájlokat nem fogja tudni.
(Nyilván gond lesz még a szóközökkel is.)
- A hozzászóláshoz be kell jelentkezni
Hogy konstruktív legyek:
- a find kimenetét soronként fordítva feldolgozva talán nem lesz olyan probléma, hogy mire átneveznénk valamit, eltűnik annak a szülőkönyvtára: find $ut | tac
- find + szóközök kezelése problémára én így szoktam ciklust szervezni:
valamiprogramaminekkimenetevan | (read line; while [ -n "$line" ]; do .....; read line; done )
- A hozzászóláshoz be kell jelentkezni
Tök jó, sikerült megint egy olyan problémát megoldani, ami teljesen más, mint amit kérdeztek. =)
- A hozzászóláshoz be kell jelentkezni
Szerintem find -depth, de nem ezt kérdezték :-)
- A hozzászóláshoz be kell jelentkezni
jajj nem!
Én a fájlokban szeretném csak cserélni, a könyvtár és fájlneveket nem akarom birizgálni...
a szóköz nem érdekel, ha van, ha nincs ki akarom cserélni...
- A hozzászóláshoz be kell jelentkezni
#! /bin/bash
usage()
{
exit 1
}
[ "x$1" == "x" ] && usage
find "$1" | sort -r | \
while read LINE
do
[ -f "$LINE" ] && sed -i 's/alma/körte/g' "$LINE"
done
azért én készítenésk mentést előtte:))
szerk.: ja, és a '| sort -r' sem kell:)
- A hozzászóláshoz be kell jelentkezni
== helyett = a helyes, ez nem c
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Mindketto mukodik - legalabbis bash kornyezetben.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
#! /bin/bash
usage()
{
exit 1
}
chacc()
{
echo "$@" | sed 's/ /_/g' | \
sed 's/[öőó]/o/g' | \
sed 's/[ŐÓÖ]/O/g'| \
sed 's/[úűü]/u/g'| \
sed 's/[ÚŰÜ]/U/g'| \
sed 's/á/a/g'| \
sed 's/Á/A/g'| \
sed 's/é/e/g'| \
sed 's/É/E/g'| \
sed 's/í/i/g'| \
sed 's/Í/I/g' | \
sed 's/_-_/-/g'
}
[ "x$1" == "x" ] && usage
find "$1" | sort -r | \
while read LINE
do
CDIR=$(dirname "$LINE")
FNAME=$(basename "$LINE")
NNAME="${CDIR}/$(chacc "$FNAME")"
# echo $NNAME
[ "$LINE" == "$NNAME" ] || mv "$LINE" "$NNAME"
done
de már egyszer ilyesmi kérdés volt
- A hozzászóláshoz be kell jelentkezni
hiányzik egy csomó szóköz, így a csövek nincsenek egymás alatt, mellé fog folyni! :D
- A hozzászóláshoz be kell jelentkezni
csak a szemléltetés miatt van így csinálva, lehessen látni rendesen mi van el... baltázva:)
- A hozzászóláshoz be kell jelentkezni
Mennyivel szebb világ volt az utf-8 előtt, amikor egy szimpla tr elég volt az ékezettelenítéshez...
- A hozzászóláshoz be kell jelentkezni
Linux alatt van inline sed is: sed -i --> nem kell az mv
"A herceg én vagyok."
- A hozzászóláshoz be kell jelentkezni
ez jo, ezt a '-i'-t en sem tudtam (valszeg lusta voltam megnezni a manualt)
Viszont a for name in `ls`; csak az adott konyvtarra megy ra, ezzel egyenerteku a
for name in *.
De vigyazni kell, ha szokoz van a filenevben, mert akkor azt ket kulon name-be teszi.
A find-nak van egy jo opcioja erre, termeszetesen kontraintuitiv kicsit.
find innentol/ -type f -exec sed ... {}
ahol a {} -t helyettesiteni fogja a szepen utvonalazott filenevekkel. A '-type f' miatt pedig csak a fileokat fogja listazni.
Ha nincs szokoz, akkor jo a :
for name in `find innentol/` ; do sed -i -e 's/alma/korte' $name ; done
- A hozzászóláshoz be kell jelentkezni
A for name in `ls` és a for name in * egyáltalán nem egyenértékű, utóbbi ugyanis nem szabdal szóközök mentén, persze később valszeg vigyázni kell hogy "$name"-ként (idézőjelek közt) hivatkozz rá.
A find-exec eddig körülbelül száznegyvenhét hup topicban lett részletesen kitárgyalva. Az exec nem rossz, de baromi lassú, mivel minden fájlra külön sed-et indít, holott egy sed akár sok-sok fájlt is képes lehet feldolgozni. Helyette -print0 kombinálva az xargs -0 paranccsal, ami gyors is, és a szóközökön sem száll el.
- A hozzászóláshoz be kell jelentkezni
elég sok "nyelvtannáci" van errefelé és az is aki megsértődik rájuk, egyikőjüket sem értem, de ez az ujj olyan volt mintha az enyémre vágtak volna :)
nem ls hanem pl find, főleg mert az paraméterként tud futtatni (-exec ... {}\;)
ideiglenes fájl kell, (legalábbis nagyon nem érdemes helyben, kivéve ha egyetlen 4gigás fájlod van de az ugye más tészta), elég egyetlen (akár mktemp-el) létrehozott)
(van egy olyan előnye hogy észlelt bibi esetén nem vész el az adat)
ps: már megint nem frissítettem válasz előtt :)
pps: ha már find, ne for hanem .. ahogy írtam :)
- A hozzászóláshoz be kell jelentkezni
Helyben módosítás kérdésköre:
A sed -i kapcsolója is ideiglenes fájlt hoz létre, nem tud mást csinálni, az "alma" szót fizikailag lehetetlenség helyben "körte" szóra cserélni, mivel a fájl teljes további tartalmát arrébb kell mozgatni. Tehát a "sed -i" egy kényelmi szolgáltatás, nem kell neked ideiglenes fájllal vacakolni. És mint ilyen kényelmi dolog, nagyon hasznos és nagyon jó.
Helyben módosítás elvileg megoldható, ha a cserélendő és az új sztring azonos hosszúságú, azonban hirtelen nem tudok olyan progiról, ami ezt megoldaná. Biztos össze lehet rá tákolni valami perl szörnyűséget, vagy írni egy C progit.
- A hozzászóláshoz be kell jelentkezni
mint kényelmi szolgáltatás lehet használni, én mint általánosságban írtam, azaz HA tud valami ellenőrzést a kész fájlon, tehát a sed-et ellenőrizendő, azaz nem bízzuk a sed-re hogy jól csinálta-e, pl mert nem csak azt lehet ellenőrizni hogy a sed azt csinálta-e amit mondtunk neki (mert mittudomén nem bugos, nem írt más program bele, stb), hanem hogy azt mondtuk neki amit szerettünk volna, azaz magunkat
- A hozzászóláshoz be kell jelentkezni
A sed -i is tud maga után backup fájlt hagyni. Különösen ha a find -exec opcióját, vagy xargs-ot használsz, szerintem sokkal egyszerűbb csak felparaméterezni a sed-et mintsem mktemp-es meg nemtommilyen mágiát építeni köré.
- A hozzászóláshoz be kell jelentkezni
így oké, nem próbáltam még, de honnan tudod hogy mi a sed backup fájla? (ha jól tippelem ugyanolyan bonyolult neki megadni vagy elkérni tőle mint a mktemp-el)
egyébként az csak a sed, a mktemp (és mint technika) pedig univerzális
- A hozzászóláshoz be kell jelentkezni
"honnan tudod..."
"ha jól tippelem..."
"... ugyanolyan bonyolult elkérni tőle..."
Könyörgöm, ember!!!
man sed
ne találgass, nézz utána!
- A hozzászóláshoz be kell jelentkezni
- azért nem néztem utána mert egyrészt nekem nem kellett, másrészt pedig elég biztos voltam a dolgomban, viszont anélkül hogy tudnám nem írom azt hogy "úgy van és pont"
- megnéztem és nem csak hogy igazam lett, hanem ráadásul neked kell megadnod a backup fájl nevét, azaz pl mktemp-el együtt kell (általános esetben) használni
- A hozzászóláshoz be kell jelentkezni
Hát kíváncsi lennék, hogy ezt hol látod. Az én sed programomnak a -i kapcsoló argumentumában egy kiterjesztést adhatsz meg, például ".bak", ezt fűzi hozzá a fájlnévhez. Szó sincs mktemp-ről.
- A hozzászóláshoz be kell jelentkezni
és ha létezik az a file.bak?
ezért írtam általános esetre, azaz ha a könyvtárat uralod, akkor egyszerű az élet
- A hozzászóláshoz be kell jelentkezni
Ha létezik, hát felülcsapja.
Ha nem ez a kívánt működés, akkor lehet előtte vizsgálni, hogy létezik-e. Azt tempfile esetén is meg kell nézni, hogy létrejött-e a fájl.
- A hozzászóláshoz be kell jelentkezni
épp erre való a mktemp, nem kell nézni van-e meg hogy létrejött-e, egy változóban kapsz egy jó fájlnevet és kész
- A hozzászóláshoz be kell jelentkezni
Kanyarodjunk vissza az eredeti kérdéshez egy picit... azt írta Koli, hogy "mappámban", nemde? Továbbá hogy rekurzívan, fene tudja hány fájlról van szó, lehet hogy százezerről.
Örülök, hogy ennyire ragaszkodsz az mktemp-hez a sokkal egyszerűbb megközelítés helyett. Össze tudnál rakni nekem egy teljes parancssort mktemp-estül? Csak úgy, kíváncsiságból... :)
- A hozzászóláshoz be kell jelentkezni
igazad van, a feladattól függ hogy kell megoldani, a szál második hozzászólásomban írtam hogy onnantól már elméleti síkon mozogtam:)
egyébként nem tudom mi olyan bonyolult:
for i in $(valami lista); do
a=$(mktemp "izlés szerinte megadni hogy hova, a fájlnevetpedig kitalálja" )
sed ... $i > $a
if [ mindneoké ]; then mv -f $i $a;
else rm $a; fi
done
értelemszerűen a "mindenoké" a "sed -i"-vel ekvivalensen lehet maga a sed visszatérési értéke, amiért a mktempet ELVIEKBEN említettem az az hogy "mindenoké" lehet pl egy grep ami megszámolja hogy tényleg prímszámú alma szerepel-e benne, ellenőrizve nem csak hogy a rendszer jól dolgozott-e hanem hogy a mi kitalált sed kifejezésünk jó-e
pps: bocsi a szerkesztésegetésekért :)
- A hozzászóláshoz be kell jelentkezni
Az egész scriptecske elejére javasolt megfelelően paraméterezett trap-et rakni, hogy egy ctrl-c vagy más "baleset" esetén ne hagyja szana meg szét a szemetét.
- A hozzászóláshoz be kell jelentkezni
Jaaaaa, megvan mit értettem félre. Azt hittem, az ideiglenes fájlt sokáig meg akarjuk tartani, mert a mindenoké programot majd az egész rakat fájl átalakítása után fogjuk kézzel futtatni :-) Te úgy gondoltad, hogy rögtön utána, aztán el is takarítva az ideiglenes fájlt. Így már teljesen értem a megközelítésedet. Mondjuk nekem még nem akadt szükségem erre, de fene tudja... bármikor jól jöhet.
- A hozzászóláshoz be kell jelentkezni
mktemp: failed to create file via template `/tmp/tmp.XXXXXXXXXX': Permission denied
- A hozzászóláshoz be kell jelentkezni
ez most komoly?
egy részmegoldás a man önelolvasódása, ott van az első oldalon (tmpdir) hogy lehet a könyvtárat megadni (sokszor praktikus az eredeti fájlrendszerbe, könyvtárba, tehát /eredeti/hely/eredetifile.bakXXX-szerű formában, mert nem másolni törölni kell ha gond van hanem csak átnevezni..), azt hogy /tmp-be miért nem tudsz írni, hmm ezt már neked kell végigjárni:)
- A hozzászóláshoz be kell jelentkezni
Halál komoly: az mktempnél sem feltételezheted, hogy márpedig az a fájl létrejön. Legalábbis, ha jót akarsz. Mert aztán a $mytempfile az üres tartalmával elég mókás dolgokat is eredményezhet, s utána már az "R0 user vagyok" szálban fogunk értekezni a témáról.
- A hozzászóláshoz be kell jelentkezni
A sed -i is tud maga után backup fájlt hagyni. Különösen ha a find -exec opcióját, vagy xargs-ot használsz, szerintem sokkal egyszerűbb csak felparaméterezni a sed-et mintsem mktemp-es meg nemtommilyen mágiát építeni köré.
- A hozzászóláshoz be kell jelentkezni
Or not. Tudtommal a busybox-os sed mintha nem tamogatna a -i kapcsolot.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
torolve
==
`Have some wine,' the March Hare said in an encouraging tone.
Alice looked all round the table, but there was nothing on it but tea.
- A hozzászóláshoz be kell jelentkezni
perl -pi -e s/foo/bar path
t
- A hozzászóláshoz be kell jelentkezni
sed -i 's/ alma / korte /g' $(grep --color=never -rl ' alma ' /az/en/kicsi/mappam)
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
NAME
rename - renames multiple files
SYNOPSIS
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
DESCRIPTION
"rename" renames the filenames supplied according to the rule specified as the
first argument. The perlexpr argument is a Perl expression which is expected to
modify the $_ string in Perl for at least some of the filenames specified. If a
given filename is not modified by the expression, it will not be renamed. If no
filenames are given on the command line, filenames will be read via standard
input.
- A hozzászóláshoz be kell jelentkezni
es ennek mi koze van az eredeti kerdeshez?
t
- A hozzászóláshoz be kell jelentkezni
az hogy lehet azért nem akar új fájlt létrehozni mert nem tudja hogy kell átnevezni, és ha valami tényleg nem zárja ki hogy átnevezéssel oldja meg a problémát akkor ez az egyetlen értelmes járható út... (lényegében ugyanaz mint fentebb a "sed -i" és a "mktemp")
- A hozzászóláshoz be kell jelentkezni
valojaban ez valasz volt a kerdesre. Amennyiben nem jo a valasz, lehet a kerdezot hibaztatni ;)
- A hozzászóláshoz be kell jelentkezni
Ami a válasz a kérdésemre:
#! /bin/bash
for i in `find`;
do
sed -i 's/alma/korte/g' $i;
done
- A hozzászóláshoz be kell jelentkezni
`find` => $(find), ill. perl -pi -e 's/egy/ketto/g' ugyanezt csinalja, kb ket hete mar irtam.
t
- A hozzászóláshoz be kell jelentkezni
Aki sed helyett perl-t lo fel, az meg is erdemli. Kabe agyu meg a vereb tipikus esete.
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
find | while read i
do
#...
done
- A hozzászóláshoz be kell jelentkezni