Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: marti..org 13 Března 2011, 16:53:12
-
Ahoj
potřeboval bych poradit s regulárním výrazem pro sed/awk.
Mám textový soubor který obsahuje cesty k souborům př:
/slozka/slozka/podslozka/soubor1
/slozka/podlozka/soubor2
/slozka/soubor3
Potřeboval odstranit název souboru (znaky za posledním lomítkem na řádku) a vůbec nevim jak na to.
Dík za radu.
-
Zkus
echo "/foo/bar/foo.txt" | sed 's/\(\/.*\/\).*/\1/'
Takže v souboru
sed 's/\(\/.*\/\).*/\1/g' soubor
a pokud chceš změnu přímo v něm tak sed -i
-
man dirname
Může se hodit :)
Ještě mě napadlo toto:
grep -o "/.*/" soubor
-
Popřípadě, kdybys to chtěl v tom awk:
awk 'BEGIN {FS="/";} /^\// { for( i=2; i < NF; i=i+1) { printf FS $i } printf "/\n" }' <filename>
S tím, že to přeskakuje řádky, co nejsou adresy.
Popřípadě takhle bez koncových lomítek:awk 'BEGIN {FS="/";} /^\// { for( i=2; i < NF; i=i+1) { printf FS $i } printf "\n" }' <filename>
-
man dirname
Tak jsem si aspoň zopakoval regulární výrazy ;D
-
man dirname
Tak jsem si aspoň zopakoval regulární výrazy ;D
Já si to taky na těhle dotazech oživuju :) Mimochodem ten tvůj sed může být kratší, třeba takto:
sed 'ss\(/.*/\).*s\1s'
;)
-
Já si to taky na těhle dotazech oživuju :) Mimochodem ten tvůj sed může být kratší, třeba takto:
sed 'ss\(/.*/\).*s\1s'
;)
Jo tak tohle je detail, já jsem zvyklej používat "/" :)
-
Já si to taky na těhle dotazech oživuju :) Mimochodem ten tvůj sed může být kratší, třeba takto:
sed 'ss\(/.*/\).*s\1s'
;)
Jo tak tohle je detail, já jsem zvyklej používat "/" :)
Je to detail, který zlepšuje přehlednost, takže když lomítko překáží, použiju jiný delimiter, protože cpát tam zpětná lomítka navíc jako escape znaky nedává smysl. Ale to ani tak nepíšu tobě, ty to víš :)
-
Ahoj díkěju všem, naprosto parádní.
přesně nějaký ten výraz pro ten sed jsem měl namysli. Ale ten příkaz dirname mě naprosto dostal :D
sed 's/\(\ /.*\ /\).*/\1/'
Jen jestli jsem tento příkaz správně pochopil tak já substituji (/.*/).* - za všechny bloky textu uzavřené / /
a že to nachrazuji za \1 tak to je nějaký způsob reverze, že právě tu substituci si nechám a zbytek zahodím?
-
Když si tohle
sed 's/\(\/.*\/\).*/\1/'
přepíšu na sed 's@\(/.*/\).*@\1@'
kde @ jsou oddělovače, tak to funguje tak, že mezi prvníma @ je to co se nahrazuje a mezi druhýma je čím nahrazuješ
Potom co je mezi \( \) to pak vyvoláš tou \1, takže hledám řetězec ve tvaru /.*/, kdy . je libovolný znak a * je 0 až nekonečně mnoho výskytů a potom to co je po /.*/ jako to .* druhý tak to je ten tvůj řetezec, kterýho se chceš zbavit. No a pak to celý jen přepíšeš tím řetězcem \1 v těch závorkách :)
-
Jo takhle funguje
dík
-
Zkusil bych to doplnit, kdyby to někdo nepobral :) Sed umožňuje v regulárním výrazu definovat pomocí kulatých závorek subřetězce, které je možné dále použít. První takový řetězec je \1, druhý \2, atd. Kulaté závorky je nutné escapovat pomocí zpětného lomítka, aby se nebraly jako součást regulárního výrazu. Například
echo 'celou fidorku mi sežral!'| sed "s/\(c\).*\(f\).*do.*\(k\)\(u\).*/\2\4\1\3/"
Regulární výraz je c.*f.*do.*ku.* a v něm jsem definoval čtyři subřetězce, jimiž řetězec daný regulárním výrazem nahradím a ulevím si :)