'\.1\.gz' ovšem nepodařilo se mi najít způsob jak bych řekl sedu(může být i jiná aplikace), aby tuto část uřízl a do proměnné uložil pouze "messages a wtmp". Pročítal sem manualové stránky regex a sed ovšem sem tam nic nenašel. Předem děkuji za každé nasměrování.
sed regulární výrazy
Marek Stopka
4. 6. 2005 13:30
sed regulární výrazy
Dobrý den snařím se napsat příkaz, který by do proměnné přiřadil z názvu souboru "messages.1.gz a wtmp.1.gz" jen část před první tečkou dostal sem se k tomu že sem napsal regulární výraz, který identifikuje část .1.gz
Dominik Sauer (neregistrovaný)
4. 6. 2005 14:01
Nový
to cele nokoli v lehu.
celé vlákno
s/^(.*)\.1\.gz$/\1/g nahradi (to co je v zavorkach).1.gz (tim, co je v zavorkach).
4. 6. 2005 14:25
Nový
reseni sedem nebo basename
celé vlákno
snad rozumim zadani
Reseni sedem
PROMENNA=`echo jmeno.1.gz | sed s/"\(.*\)\.1\.gz"/"\1"/`
IMHO lepsi je:
PROMENNA=`basename jmeno.1.gz .1.gz`
Reseni sedem
PROMENNA=`echo jmeno.1.gz | sed s/"\(.*\)\.1\.gz"/"\1"/`
IMHO lepsi je:
PROMENNA=`basename jmeno.1.gz .1.gz`
4. 6. 2005 14:34
Nový
Re: reseni sedem nebo basename
celé vlákno
Moc ti díky řešení číslo 2 funguje, řešení číslo 1 jsem nezkoušel.
miEro (neregistrovaný)
4. 6. 2005 15:26
Nový
Re: reseni sedem nebo basename
celé vlákno
alebo este jednoduchsie pomocou
PROMENNA=jmeno.1.gz
echo ${PROMENNA%.1.gz}
PROMENNA=jmeno.1.gz
echo ${PROMENNA%.1.gz}
4. 6. 2005 19:22
Nový
Re: reseni sedem nebo basename
celé vlákno
Tak ještě bych sem přidal jeden dotaz snad to nebude vadit nevíte proč mi toto nefunguje:
for file in *.1.gz; do
mv $file $(echo ${file%.1.gz})
done
skoušel sem i toto:
for file in *.1.gz; do
tmp2=$(echo ${file%.1.gz})
mv $file $tmp2
done
ale to taky nefunguje.
4. 6. 2005 22:37
Nový
Re: reseni sedem nebo basename
celé vlákno
netreba hned vsetko do pismenka prepisovat :-))
inak uvodzovky su dolezite, inak budu robit problemy subory s medzerami
asi to chcete aj rozbalit, ze?
preco nie rovno?
for file in *.1.gz; do
zcat \"${file%.1.gz}\" > \"$file\"
done
inak pekne funguje aj zcat FILE.gz | less
Kit (neregistrovaný)
5. 6. 2005 8:56
Nový
Re: reseni sedem nebo basename
celé vlákno
zcat IMHO pouze zavolá gunzip, je tedy zbytečný.
for file in *.1.gz; do
gunzip <"$file" >"${file%.1.gz}"
done
ale tato konstrukce je zbytečně složitá, pro rozbalení více souborů stačí zadat:
gunzip *.1.gz
Kit (neregistrovaný)
5. 6. 2005 9:00
Nový
Re: reseni sedem nebo basename
celé vlákno
Ještě pěkně funguje
less FILE.gz
6. 6. 2005 19:39
Nový
Re: reseni sedem nebo basename
celé vlákno
Vy máte na disku soubory s názvem v uvozovkách? Něco jako
$ ls \"*\"
"blbejnazev"
$ ls \"*\"
"blbejnazev"
Kit (neregistrovaný)
5. 6. 2005 8:46
Nový
Re: reseni sedem nebo basename
celé vlákno
Je tam navíc echo, které je v tomto případě zbytečné:
for file in *.1.gz; do
mv "$file" "${file%.1.gz}"
done
Nezapomínejte na uvozovky, jinak si koledujete...
Kit (neregistrovaný)
5. 6. 2005 9:07
Nový
Re: reseni sedem nebo basename
celé vlákno
Ještě mě napadlo jedno řešení, pokud není třeba rozbalovat, ale jen odstranit přípony:
rename ".1.gz" "" *.1.gz
6. 6. 2005 16:28
Nový
Re: reseni sedem nebo basename
celé vlákno
No to by musel mý ten správný rename (rozuměj třeba ten co je v FC). U mě by to bylo třeba
rename 's/\.1\.gz$//' *.1.gz
(perlutils rename)
rename 's/\.1\.gz$//' *.1.gz
(perlutils rename)
barney (neregistrovaný)
4. 6. 2005 19:39
Nový
hmm zlozitejsie by to neslo ?
celé vlákno
echo messages.1.gz | sed -e 's/\.1\.gz$//'
6. 6. 2005 16:24
Nový
Re: reseni sedem nebo basename
celé vlákno
Dělat 2x fork+exec a 2x pipe v prvním případě a jednou fork+exec a jedna pipe v druhém případě místo
PROMENNA=${PROMENNA%%.*}
nebo
PROMENNA=${PROMENNA%.1.gz}
je dnes nějaká móda?
PROMENNA=${PROMENNA%%.*}
nebo
PROMENNA=${PROMENNA%.1.gz}
je dnes nějaká móda?
uživatel si přál zůstat v anonymitě
4. 6. 2005 14:49
Nový
cut ?!?!
celé vlákno
jezis... nie je jednoduchsie pouzit:
echo ... | cut -d'.' -f 1
????
naco pouzivat kanon na vrabce (sed)
echo ... | cut -d'.' -f 1
????
naco pouzivat kanon na vrabce (sed)
uživatel si přál zůstat v anonymitě
4. 6. 2005 14:51
Nový
Re: cut ?!?!
celé vlákno
ehm... sorry... to basename som si nevsimol :) mae culpa
uživatel si přál zůstat v anonymitě
4. 6. 2005 15:32
Nový
Re: cut ?!?!
celé vlákno
Toto elegantni reseni s cut, ktere neni kanon na vrabce, je typicka ukazka spatneho programovani....
Zkusim-li tomu zadat jan.novak.1.gz,
vypadne ...chvilka napeti.... "jan" misto "jan.novak", jak by melo dle zadani a (meho) zdraveho rozumu byt.
Vyse uvedene reseni se sedem funguje lepe....Osobne bych asi pouzil basename, protoze pri prvnim pohledu
na program vim, ze to urizne priponu a nemusim studovat ten strasne neprehledny regularni
vyraz pro sed (perl,...).
Jeste bych dodal ze basename oreze take cestu k souboru, tj. z "/home/jan.novak.1.gz" zbude jenom "jan.novak". (man cut, man basename)
Zkusim-li tomu zadat jan.novak.1.gz,
vypadne ...chvilka napeti.... "jan" misto "jan.novak", jak by melo dle zadani a (meho) zdraveho rozumu byt.
Vyse uvedene reseni se sedem funguje lepe....Osobne bych asi pouzil basename, protoze pri prvnim pohledu
na program vim, ze to urizne priponu a nemusim studovat ten strasne neprehledny regularni
vyraz pro sed (perl,...).
Jeste bych dodal ze basename oreze take cestu k souboru, tj. z "/home/jan.novak.1.gz" zbude jenom "jan.novak". (man cut, man basename)
6. 6. 2005 16:14
Nový
Re: cut ?!?!
celé vlákno
Co to máte za basename? moje basename udělá tohle
$ basename /home/jan.novak.1.gz
jan.novak.1.gz
jinak v zadání je doslova napsáno "jen část před první tečkou"
takže na to máme ${var%%.*} které dělá přesně tohle
jinak další otázka v diskusi bylo na
for i in *.1.gz
do
mv "$i" "${i%.1.gz}"
done
P.S.: To je nějaká nová móda radit blbě a ani si to neověřit?
$ basename /home/jan.novak.1.gz
jan.novak.1.gz
jinak v zadání je doslova napsáno "jen část před první tečkou"
takže na to máme ${var%%.*} které dělá přesně tohle
jinak další otázka v diskusi bylo na
for i in *.1.gz
do
mv "$i" "${i%.1.gz}"
done
P.S.: To je nějaká nová móda radit blbě a ani si to neověřit?
6. 6. 2005 16:40
Nový
Re: cut ?!?!
celé vlákno
Nevšim jsem si, že už víše je to s basename ukázáno správně. Jinak basename je berlička pro shelly co neumí konstrukce ${var#pattern} ${var##pattern} ${var%pattern} ${var%%pattern} což je csh, kcsh, další klony csh a některé minimalistické shelly. Od těch dob, co tohle umí i sh je zbytečné spouštět podproces basename a nutit shell parsovat jeho výstup.
basename() { local a="${1##*/}"; [ -z "$2" ] && echo $a || echo ${a%$2}; }
basename() { local a="${1##*/}"; [ -z "$2" ] && echo $a || echo ${a%$2}; }
6. 6. 2005 17:37
Nový
Re: cut ?!?!
celé vlákno
Trochu brutálnější verze
basename() { [ -n "$2" ] && set -- "${1%$2}"; echo ${1##*/}; }
stejně se to uvnitř skriptu bude dělat prvním způsobem, protože nebudu přece dělat podproces kvůli přiřazení a=$(basename bla/bla/bla.bl) (a taky se mi nechce koukat do zdrojáku jestli to náhodou shell nějak neoptimalizuje).
Nebo si můžu udělat funkci, která rovnou přiřadí do proměné
basenameset() { [ $# -ge 2 ] && { eval $1=\"${2##*/}\"; [ -n "$3" ] && eval $1='"${'$1'%$3}"'; } }
basename() { [ -n "$2" ] && set -- "${1%$2}"; echo ${1##*/}; }
stejně se to uvnitř skriptu bude dělat prvním způsobem, protože nebudu přece dělat podproces kvůli přiřazení a=$(basename bla/bla/bla.bl) (a taky se mi nechce koukat do zdrojáku jestli to náhodou shell nějak neoptimalizuje).
Nebo si můžu udělat funkci, která rovnou přiřadí do proměné
basenameset() { [ $# -ge 2 ] && { eval $1=\"${2##*/}\"; [ -n "$3" ] && eval $1='"${'$1'%$3}"'; } }
6. 6. 2005 18:01
Nový
Re: cut ?!?!
celé vlákno
Trošku elegantnější
basenameset() { [ -n "$3" ] && set -- $1 "${2%$3}"; [ $# -ge 2 ] && eval $1="${2##*/}"; }
basenameset() { [ -n "$3" ] && set -- $1 "${2%$3}"; [ $# -ge 2 ] && eval $1="${2##*/}"; }
6. 6. 2005 18:05
Nový
Re: cut ?!?!
celé vlákno
V tom evalu musí být uvozovky eskejpnuty jinak to nezebere názvy s mezerou a ten první parametr musí být platné jméno proměné, takže taky žádné skopičiny.
basenameset() { [ -n "$3" ] && set -- $1 "${2%$3}"; [ $# -ge 2 ] && eval $1=\"${2##*/}\"; }
basenameset() { [ -n "$3" ] && set -- $1 "${2%$3}"; [ $# -ge 2 ] && eval $1=\"${2##*/}\"; }
7. 6. 2005 8:23
Nový
Re: cut ?!?!
celé vlákno
Trošku vylepšená superbrutus verze s ošetřením parametrů a bez zbytečného testu na třetí parametr.
basenameset() { set -- "$1" "${2%$3}"; case "$1" in [^a-zA-Z]*|*[^a-zA-Z0-9]*);; ?*) eval $1=\"${2##*/}\";; esac }
basenameset() { set -- "$1" "${2%$3}"; case "$1" in [^a-zA-Z]*|*[^a-zA-Z0-9]*);; ?*) eval $1=\"${2##*/}\";; esac }
uživatel si přál zůstat v anonymitě
6. 6. 2005 7:48
Nový
co treba takhle
celé vlákno
no nevim... me stacilo toto
STR="messages.1.gz"
echo $STR|cut -d. -f1
STR="messages.1.gz"
echo $STR|cut -d. -f1
6. 6. 2005 16:19
Nový
Re: co treba takhle
celé vlákno
No hlavně že máme zbytečně moc systémových prostředků. Dvakrát fork+exec a jedna roura navíc dnes už nikoho nebolí. Jen toho nikdo nesmí chtít udělat milionkrát, že?
uživatel si přál zůstat v anonymitě
6. 6. 2005 17:31
Nový
Re: co treba takhle
celé vlákno
ehm? preco dva krat fork+exec? neni to len raz? (len na cut?)
6. 6. 2005 17:51
Nový
Re: co treba takhle
celé vlákno
Máte pravdu. Zdá se, že to jde udělat s jedním fork+exec
schematicky:
pipe()
fork()
potomek: exec(cut)
write()
wait(potomek)
jenže vy to tam nikde nepřiřazujete do proměnné (což je požadavek v zadání) a na to se shell ještě jednou forkne na realizaci $() a tak jsou to dvakrát fork a jednou exec a jedno pipe.
schematicky:
pipe()
fork()
potomek: exec(cut)
write()
wait(potomek)
jenže vy to tam nikde nepřiřazujete do proměnné (což je požadavek v zadání) a na to se shell ještě jednou forkne na realizaci $() a tak jsou to dvakrát fork a jednou exec a jedno pipe.
uživatel si přál zůstat v anonymitě
6. 6. 2005 18:35
Nový
Re: co treba takhle
celé vlákno
hm... njn... ale stejne nechapem naco robit nieco v shelli efektivne. IMHO v shelli urobim niektore veci hlavne rychlo, raz ich pouzijem a nasledne zahodim. Ked chcem nieco spravit efektivne, tak to stejne v shelli robit nebudem, lebo tomu forkovani/execovani sa aj tak nevyhnem...
6. 6. 2005 19:36
Nový
Re: co treba takhle
celé vlákno
Proč něco v shellu dělat efektivně? No třeba potřebuju rychle ad hoc udělat nad několika sty tisici souboru v několika set adresářích. To se pak hodí vědět, že na
find -type f -name '*.mp3' -exec rm {} \;
si počkám podstatně déle než na
find -type f -name '*.mp3' -print0 | xargs -0 rm
no a když je budu chtít přejmenovat několik tisíc souborů pomocí
for i in *.jpg; do mv "$i" "$(echo $i|sed 's/\.jpg$/\.jpeg/')"; done
je dobré vědět, že to není zrovna dobrý nápad a budu to mít mnohem dřív hotové, když napíšu
for i in *.jpg; do mv "$i" "${i%.jpg}.jpeg"; done
a vůbec nejdřív se dočkám výsledku s
find -maxdepth 1 -type f -name '*.jpg' -print0 | xargs -0 rename 's/\.jpg/.jpeg/'
(verze pro opravdu velké množství souborů v adresáři s hodně velkým množstvím souborů s jiným jménem než *.jpg, 10000 a více, jinak si vystačím bez findu)
find -type f -name '*.mp3' -exec rm {} \;
si počkám podstatně déle než na
find -type f -name '*.mp3' -print0 | xargs -0 rm
no a když je budu chtít přejmenovat několik tisíc souborů pomocí
for i in *.jpg; do mv "$i" "$(echo $i|sed 's/\.jpg$/\.jpeg/')"; done
je dobré vědět, že to není zrovna dobrý nápad a budu to mít mnohem dřív hotové, když napíšu
for i in *.jpg; do mv "$i" "${i%.jpg}.jpeg"; done
a vůbec nejdřív se dočkám výsledku s
find -maxdepth 1 -type f -name '*.jpg' -print0 | xargs -0 rename 's/\.jpg/.jpeg/'
(verze pro opravdu velké množství souborů v adresáři s hodně velkým množstvím souborů s jiným jménem než *.jpg, 10000 a více, jinak si vystačím bez findu)
uživatel si přál zůstat v anonymitě
6. 6. 2005 20:57
Nový
Re: co treba takhle
celé vlákno
"
je dobré vědět, že to není zrovna dobrý nápad a budu to mít mnohem dřív hotové, když napíšu
for i in *.jpg; do mv "$i" "${i%.jpg}.jpeg"; done
"
:)) to snad nemyslite vazne :D nad "nekolik tisic soubormi" vam toto stejne selze kvuli tomu "i in *.jpg" a tomu, ze sa to rozvinie na nieco priiiilis dlhe a prekroci to nejaky limit... takze bez toho findu si stejne nepomozete....
je dobré vědět, že to není zrovna dobrý nápad a budu to mít mnohem dřív hotové, když napíšu
for i in *.jpg; do mv "$i" "${i%.jpg}.jpeg"; done
"
:)) to snad nemyslite vazne :D nad "nekolik tisic soubormi" vam toto stejne selze kvuli tomu "i in *.jpg" a tomu, ze sa to rozvinie na nieco priiiilis dlhe a prekroci to nejaky limit... takze bez toho findu si stejne nepomozete....
7. 6. 2005 7:51
Nový
Re: co treba takhle
celé vlákno
Další expert co jen planě plácá a nevyzkouší si to? Tak si to zkuste! Vtip je v tom, že se to nerozvine, ale shell to udělá chytře. A příště, když nevím, tak to zkusím.
7. 6. 2005 7:59
Nový
Re: co treba takhle
celé vlákno
$ ls
$ for((i=0;$i<10000;i++)); do touch zbytecne_dlouhej_prefix_$i; done
$ echo *
zbytecne_dlouhej_prefix_0 zbytecne_dlouhej_prefix_1 zbytecne_dlouhej_prefix_2 ... zbytecne_dlouhej_prefix_9999
$ ls *
bash: /bin/ls: Příliš dlouhý seznam argumentů
$ for i in zbytecne_dlouhej_prefix_*; do rm $i; done
$ ls
$
$ for((i=0;$i<10000;i++)); do touch zbytecne_dlouhej_prefix_$i; done
$ echo *
zbytecne_dlouhej_prefix_0 zbytecne_dlouhej_prefix_1 zbytecne_dlouhej_prefix_2 ... zbytecne_dlouhej_prefix_9999
$ ls *
bash: /bin/ls: Příliš dlouhý seznam argumentů
$ for i in zbytecne_dlouhej_prefix_*; do rm $i; done
$ ls
$
Školení: Linux – Firewall, Samba, VPN
Na třídenním školení se naučíte nainstalovat a spravovat Firewall a Router, SAMBA Doménový a Souborový server. Dále si zprovozníte vlastní, zabezpečený VPN server.
Podrobnější informace a přihláška

