linux textutils - comm, diff, etc

Fórumok

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

Hozzászólások

Bocs, kicsit késő van hozzá, de talán lesz még időm agyalni is rajta.

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)

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.)

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.

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

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.

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

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.

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