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: Robert1106 02 Června 2009, 20:57:23

Název: shel script [vyřešeno]
Přispěvatel: Robert1106 02 Června 2009, 20:57:23
Ahoj, ak by bol niekto ochotný mi prosím pomôcť so shell skriptom bol by som mu naozaj zaviazaný  ;)

Mam dva .txt súbory. Napíš shell skript ktorý vypiše slova čo sú v prvom ale niesu v druhom.

Výpis všetkých slov riešim takto:

cat `find . -type f -name \jeden.txt  | grep '/[^/]\+$'`
cat `find . -type f -name \dva.txt  | grep '/[^/]\+$'`

,ale ďalej sa neviem dostať.

EDIT: Domáca úloha to nieje ( je skúškové obdobie )
Název: Re: shel script
Přispěvatel: premet 02 Června 2009, 21:35:37
Pokud máš jedno slovo na řádek, tak by mělo fungovat jednoduše něco takovýho
Kód: [Vybrat]
#!/bin/bash

cat soubor | while read line
    do     
       if [ -z "`grep $line soubor1`" ]; then
          echo "$line" >> rozdil.txt
       fi
done
Tím se ti to uloží do souboru, nebo to nemusíš přesměrovávat a rovnou to můžeš vypsat.
Název: Re: shel script
Přispěvatel: premet 02 Června 2009, 21:44:08
Pokud to není jedno slovo na řádek tak mě ted bohužel nic nenapadá, nevím jak donutit v Bashi číst po slovech, to by mě i do budoucna zajímalo nějakej způsob.
Název: Re: shel script
Přispěvatel: premet 02 Června 2009, 22:08:01
Ha a už jsem i sám přišel jak vypsat slova po jednom, když jich je víc na řádku. Snad to tak je funkční, teda aspon u mě funguje a nevšímejte si těch slov, je to improvizace  ;D
Kód: [Vybrat]
[prema@fedora ~]$ cat foo1
ubuntu kubuntu xubuntu medibuntu blubuntu kravinbuntu
fedora fedora1 fedora2
debian lenny sid
Kód: [Vybrat]
[prema@fedora ~]$ sed 's/\(\w*\ \)/\1\n/g' foo1
ubuntu
kubuntu
xubuntu
medibuntu
blubuntu
kravinbuntu
fedora
fedora1
fedora2
debian
lenny
sid
Název: Re: shel script
Přispěvatel: arrange 02 Června 2009, 22:15:51
Kód: [Vybrat]
echo "Pokud to není jedno slovo na řádek tak mě ted bohužel nic nenapadá, nevím jak donutit v Bashi číst po 55slovech, 5897 to @djfh by mě i do budoucna zajímalo nějakej způsob." > /tmp/a
$ for i in `cat /tmp/a`; do echo $i; done
Pokud
to
není
jedno
slovo
na
řádek
tak

ted
bohužel
nic
nenapadá,
nevím
jak
donutit
v
Bashi
číst
po
55slovech,
5897
to
@djfh
by

i
do
budoucna
zajímalo
nějakej
způsob.

$ sed 's:\ :\n:g' /tmp/a | grep -E '^[a-žA-Ž]+'
Pokud
to
není
jedno
slovo
na
řádek
tak

ted
bohužel
nic
nenapadá,
nevím
jak
donutit
v
Bashi
číst
po
to
by

i
do
budoucna
zajímalo
nějakej
způsob.
Název: Re: shel script
Přispěvatel: premet 02 Června 2009, 22:21:58
Arrange: Tak ten první způsob je dobrej, tohle by mě nikdy nenapadlo  ;D

EDIT: A jak koukám na ten druhej tak taky ne  :)
Název: Re: shel script
Přispěvatel: Robert1106 02 Června 2009, 22:56:42
Ďakujem vám za pomoc. Takýto spôsob by ma nenapadol.  :)
Len škoda že slová musia začínať na novom riadku, skúsim sa stým ešte potrápiť.
Název: Re: shel script
Přispěvatel: petergula 02 Června 2009, 23:04:38
No myslim, ze Ti poradili aj pre pripad, ked slova nezacinaju na novom riadku, skus lepsie poprecitat dalsie prispevky a nebudes sa musiet trapit, staci im podakovat :), ci som nieco ja zle pochopil?
Název: Re: shel script
Přispěvatel: Robert1106 02 Června 2009, 23:12:02
Nie je tam všetko podla tohoto to viem zlepiť do jedného shell scriptu. Len mi trochu dlho trvalo kým som to pochopil.
Týmto všetkým ďakujem sa pomoc a ospravedlňujem sa za nedorozumenie.
Název: Re: shel script [vyřešeno]
Přispěvatel: Martin Kiklhorn 03 Června 2009, 00:08:58
Kód: [Vybrat]
#!/bin/bash
#porovnej.sh

for i in `cat $1`; do echo $i; done | sort | uniq > /tmp/prvnitrideny.tmp
for i in `cat $2`; do echo $i; done | sort | uniq > /tmp/druhytrideny.tmp

cat /tmp/prvnitrideny.tmp | while read line
    do
       if [ -z "`grep $line /tmp/druhytrideny.tmp`" ]; then
          echo "$line"
       fi
done

rm /tmp/prvnitrideny.tmp
rm /tmp/druhytrideny.tmp

./porovnej.sh prvni.txt druhy.txt
Název: Re: shel script [vyřešeno]
Přispěvatel: Yontalcar 03 Června 2009, 12:21:29
@Premet
grep při nenelezení řetězce vrací 1, takže test není potřeba

jinak tu evidentně nikdo neřeší existenci interpunkce
Kód: [Vybrat]
#!/bin/bash
echo "$*"|egrep -q '(-h|--help|-\?)'&&{ cat <<EOF
Searches for words, which are in DOCUMENT1, but not in DOCUMENT2
Usage: $0 DOCUMENT1 DOCUMENT2
EOF
exit 0
}

cat $1|sed 's/\W\+/\n/g'|sed '/[0-9]/d;/^$/d'|while read line;do
    grep -q "\<${line}\>" $2||echo "${line}"
done

exit 0

tato verze je pajpovzdorná:
Kód: [Vybrat]
#!/bin/bash
function Exit(){
    [ -f "${doc2}" ]&&rm "${doc2}"
    exit $1
}

trap Exit INT
trap Exit TERM

echo "$*"|egrep -q '(-h|--help|-\?)'&&{ cat <<EOF
Searches for words, which are in DOCUMENT1, but not in DOCUMENT2
Usage: $0 DOCUMENT1 DOCUMENT2
EOF
exit 0
}

doc2="$(mktemp)"
cat $2|sed 's/\W\+/\n/g'|sed '/[0-9]/d;/^$/d'|sort|uniq -i > ${doc2}

cat $1|sed 's/\W\+/\n/g'|sed '/[0-9]/d;/^$/d'|sort|uniq -i|while read line;do
    grep -iq "^${line}$" ${doc2}||echo "${line}"
done

Exit 0
Edit: update 2.skriptu: ignoruje velikost písmen a měl by být rychlejší
Název: Re: shel script [vyřešeno]
Přispěvatel: arrange 03 Června 2009, 20:52:08
Kód: [Vybrat]
cat $1|sed 's/\W\+/\n/g'|sed '/[0-9]/d;/^$/d'|while read line;do
    grep -q "\<${line}\>" $2||echo "${line}"
done
Paráda, funguje to perfektně i na šílených textech třeba s kódem.

Poddotaz: musí v tom sedu být \+, respektive jakou tam má funkci, pokud testuji znaky na ne-slovo (\W)?
Název: Re: shel script [vyřešeno]
Přispěvatel: Robert1106 03 Června 2009, 21:19:57
Vav, ste mi naozaj pomohli ďakujem. Inak už som ako tak vyriešil verziu keď vypíše slová ktoré sa nachádzajú v oboch súboroch.

Kód: [Vybrat]
#!/bin/bash

for slovo1 in `cat $1`
do

pom=0

for slovo2 in `cat $2`
do

if test ${slovo1} = ${slovo2}
then
pom=1
fi
done

if test ${pom} = 1
then
vysl=${vysl}' '${slovo1}
fi
done

echo ${vysl}
Název: Re: shel script [vyřešeno]
Přispěvatel: Yontalcar 03 Června 2009, 21:27:19
Kód: [Vybrat]
cat $1|sed 's/\W\+/\n/g'|sed '/[0-9]/d;/^$/d'|while read line;do
    grep -q "\<${line}\>" $2||echo "${line}"
done
Paráda, funguje to perfektně i na šílených textech třeba s kódem.

Poddotaz: musí v tom sedu být \+, respektive jakou tam má funkci, pokud testuji znaky na ne-slovo (\W)?
\+ značí jednou nebo vícekrát předchozí znak - je to tam proto, aby se na \n změnila rovnou celá skupina nealfanumerických znaků - teoreticky to tam být nemusí, protože v dalším navázaném sedu stejně mažu prázdné řádky
Název: Re: shel script [vyřešeno]
Přispěvatel: arrange 03 Června 2009, 21:38:45
\+ značí jednou nebo vícekrát předchozí znak - je to tam proto, aby se na \n změnila rovnou celá skupina nealfanumerických znaků - teoreticky to tam být nemusí, protože v dalším navázaném sedu stejně mažu prázdné řádky
Už jasný, díky, \W - nejedná se totiž o "ne-slovo", ale o "nealfanumerický" znak.
Název: Re: shel script [vyřešeno]
Přispěvatel: Yontalcar 03 Června 2009, 22:16:54
@Robert1106
nechci ti kazit radost, ale na mojí dvojici testovacích souborů je ten tvůj skript nesrovnatelně horší:
a) trvá asi 10× dýl (edit: tak teď už ~18×)
b) 2 slova nenašel
c) tahá s sebou nepořádek ve formě uvozovek, čárek, vykřičníků etc.
d) shluky uvozovek, čárek, vykřičníků etc. považuje za slova

pokud chceš ten můj skript upravit, aby hledal slova, která jsou v obou souborech, změň na řádku
Kód: [Vybrat]
    grep -q "\<${line}\>" $2||echo "${line}"|| za &&

také by nevadilo kdybys ve skriptech používal odsazení :)