Sziasztok,
A comm paranccsal kapcsolatosan szeretnék kérdezni, azt keresem a 4 fájlban, ami közös:
Ha van 4 file-om, file1,file2,file3,file4 a nevük,
mindegyiknek a tartalma:
a
b
c
d
Ha ezt írom be a terminálba, hogy:
comm -12 file1 file2 | comm -12 - file3 | comm -12 - file4
Akkor szépen kiadja a közös sorokat, az abcd-t tehát működik. De jó ez így? Nekem azok a sorok kellenek, amelyek mind a 4 fájlban szerepelnek. A comm alapesetben csak 2 fájlt hasonlít össze, ezért pipolom tovább, de nem vagyok biztos benne a kellő rutin hiányában, hogy jó -e az elgondolásom és valóban azt csinálja -e, amit szeretnék
De szerintetek, hogyha több száz, több ezer soros az egyik fájl, akkor is működne?
Vagy előtte az összehasonlítandó fájlokat numerikus sorrendbe kellene tenni, ha mondjuk hash-ek lennének benne véletlenül?
Megfelelő erre a feladatra a comm parancs, mint a diff ellentétje?
Szerintetek, ha nincs sorrendiség, akkor megadjam paraméterként a --check-order -t?, tehát nézzen így ki inkább a parancs?
comm -12 --check-order file1 file2 | comm -12 --check-order - file3 | comm -12 --check-order - file4
De így hibára fut, hogy megváltoztatom valamelyik fájlban a sorrendet.
Lehetne esetleg valahogy összefűzni 1 parancsba az egészet, hogy ne kelljen külön végigmenni a fájlokon így:
file1 | sort -n > file1sorted
file2 | sort -n > file2sorted
file3 | sort -n > file3sorted
file4 | sort -n > file4sorted
comm -12 file1sorted file2sorted | comm -12 - file3sorted | comm -12 - file4sorted
Az xargs jut eszembe erre, de még sose használtam, nem lehetne a segítségével átadni a comm nak a sort -n kimenetét?
Ilyesmire gondolok, de tudom, hogy ez így nem jó:
comm -12 (cat file1|sort -n) (cat file2|sort -n) | comm -12 - (cat file3|sort -n) | comm -12 - (cat file4|sort -n)
Köszi előre is a segítséget!
Üdv,
Zoli
- 9167 megtekintés
Hozzászólások
Csak bedobom mert sietek de érdekelne majd a végeredmény is :)
http://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools
- A hozzászóláshoz be kell jelentkezni
Bocs, kicsit késő van hozzá, de talán lesz még időm agyalni is rajta.
- A hozzászóláshoz be kell jelentkezni
A man szerint: "compare two sorted files", tehát igen,előtte sort-olnod kell a fileokat. Az eredeti pipelineod ettől eltekintve egyébként jó.
A "helyben" sortolást a következőképpen lehet megcsinálni:
comm -12 <(sort -n file1) <(sort -n file2) | comm -12 - <(sort -n file3) | comm -12 - <(sort -n file4)
- A hozzászóláshoz be kell jelentkezni
Nem teljesen. A te manualod sem ezt írja, de az enyém (ebben) egyértelműbb:
"The comm utility reads file1 and file2, which should be sorted lexically"
(én a "should" helyett a bunkó "must" formát használnám az érzékeltetés érdekében). Szóval jó ez, csak nem numerikusan hanem ABC-rendben kell rendezni. Ja, éslegyen sokkal rondább:
$ comm -12 <(comm -12 <(sort ize1) <(sort ize2) ) <(comm -12 <(sort ize3) <(sort ize4) )
(Ja, ez még tán működésben sem tér el a csöveket használó verziótól, csak olvashatatlanabb.)
Szerk: amúgy nem tudom, hogy vajon valóban van-e jelentősége az ABC- vagy számsorrend résznek, de gonsolom az biztos, hogy ugyanúgy kell rendezni minden (de mivel a nuumerikus az plusz opciót igényel, tán mégis el kéne hagyni.)
- A hozzászóláshoz be kell jelentkezni
Mindkettőtöknek köszönöm szépen!
Pont erre gondoltam. Nem is jutott eszembe, hogy a "<" jelet használjam erre, így tökéletes, ma is tanultam valamit.
-- Zoli
- A hozzászóláshoz be kell jelentkezni
Igazad van, megzavart kicsit hogy az eredeti kérdésben numerikus sort szerepelt, azt gondoltam hogy arra van szüksége a kérdezőnek és közben megfeledkeztem arről, hogy vajon a comm-nak mire van szüksége :)
Én is gondoltam a pipeline helyett a többszörös beágyazásra, de szerintem az se nem hatékonyabb, se nem olvashatóbb. És úgyis mindig n-1 db comm parancsra lesz szükség.
- A hozzászóláshoz be kell jelentkezni
(dup)
- A hozzászóláshoz be kell jelentkezni
Sziasztok,
script írás közben vettem észre, hogy az echo * ra kilistázza a fájlokat, most már persze így használom: echo '*', de ennek mi az oka?
-- Zoli
- A hozzászóláshoz be kell jelentkezni
Ezt azért simán elég csak végiggondolni :-). A shell a parancssorban levő joker-karaktereknek megfelelő fájlneveket behelyettesíti, majd végrehajtja az így létrejött parancsot. Tehát ha az aktuális könyvtárban van alma, körte és narancs nevű fájlok, akkor a * helyére ezek kerülnek, ABC-rendben. Tehát előáll az "echo alma körte narancs" parancs. Eredménye pedig olyan, mintha kiadtad volna az opciómentes /bin/ls-t.
- A hozzászóláshoz be kell jelentkezni
:-)köszi
De az echo ******** is ugyanezt csinalja, azert szerintem ez egy bug. Vagy inkább feature?
-- Zoli
- A hozzászóláshoz be kell jelentkezni
Miért kellene máshogy viselkednie annak, hogy N x "akárhány akármilyen karakter", mint annak, hogy "akárhány akármilyen karakter"?
- A hozzászóláshoz be kell jelentkezni
Nem. Következik a definícióból, ahogy előttem már leírták.
- A hozzászóláshoz be kell jelentkezni
Sziasztok,
Sok fájlt szeretnék átnevezni, a rename -mel.
A fájlok:
track01.cdda.flac
track02.cdda.flac
...
track18.cdda.flac
Azt szeretném, hogy ne legyegy ott a cdda, vagyis így nézzenek ki:
track01.flac
track02.flac
...
track18.flac
Így próbáltam eddig:
rename 's/track..\.flac/track[0-9][0-9]\.flac/' *.flac
És így sem megy:
rename 'y/cdda\.//' *.flac
És így sem működik:
rename -v 'y/track[0-9][0-9]cdda\.//' *.flac
Erre elrontotta az összes fájlnevet:
rename -v 'y/track[0-9][0-9]cdda\.flac/track[0-9][0-9]\.flac/' *.flac
A parancs hiba nélkül lefut, csak nem nevezi át a fájlokat. A verbose mód sem mond semmit.
-- Zoli
- A hozzászóláshoz be kell jelentkezni
Egyszerűen: rename -v "cdda.flac" "flac" *.flac
- A hozzászóláshoz be kell jelentkezni
Ez nem működik sajnos.
Kipróbáltam, létrehozatm egy pár fájlt, és ráengedtem, amit írtál:
for i in `seq -w 1 18`; do touch track$i.cdda.flac; done
rename -v "cdda.flac" "flac" *.flac
-- Zoli
- A hozzászóláshoz be kell jelentkezni
Az a baj, hogy nem vagy tisztában a perl s/// és a y/// operátorainak feladatával.
Az s/ezt/erre/ az "ezt" reguláris kifejezést cseréli az operandusában az "erre" sztringre.
Az y/1234/abcd/ viszont az "1234" karaktersorozatának n-edik elemét cseréli az "abcd" karaktersorozat n-edik elemére az operandusában.
Esetedben pl. a
rename 's/cdda\.//' *.flac
lehetett volna egy használható megfogalmazás.
Az általános megoldás pedig a
man perlop
"Quote-Like Operators" című bekezdéseinek átolvasása.
- A hozzászóláshoz be kell jelentkezni
Szerintem hasonlít a sed re.
Valóban nem vagyok tisztában a perl e két operandusával, viszont működik a javaslatod (rename 's/cdda\.//' *.flac), köszi, be is építem a scriptembe.
Keresem a perlop ban az y/mit/mire/ részt, de nem igazán találom, azt meg nem értem, hogy miért kellene vagy tisztába lenni a perl operandusával, ahhoz, hogy használja az ember a rename parancsot.
A rename manjában 1 sor szól erről :
To translate uppercase names to lower, you'd use
rename 'y/A-Z/a-z/' *
Az én esetemre ez nem is felelt meg, a doksiban ez a számomra zagyva pár sor lelhető:
For example, to rename all files matching "*.bak" to strip the
extension, you might say
rename 's/\.bak$//' *.bak
Én csak annyit fogok fel a másodikból, hogy minden .bak ra végződő fájlból kitörli a .bak ot...
nem tudom, hogy ez kit világosított meg.
Ebből a 2 példából nem igazán érthető meg számomra az y os és az s verziós helyettesítés közötti különbség.
Ezért jó ez a fórum, mert 1 adott dolog miatt nem kell 200 oldalt olvasni... nem fogok csak azért perl dokumentációt olvasgatni, hogy ezt a kis átnevezést megoldjam - inkább megkérdezem, és szerencsére mindig van valaki, aki tud segíteni,amit ezúton is köszönök.
Köszi
-- Zoli
- A hozzászóláshoz be kell jelentkezni