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
-
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 )
-
Pokud máš jedno slovo na řádek, tak by mělo fungovat jednoduše něco takovýho
#!/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.
-
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.
-
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
[prema@fedora ~]$ cat foo1
ubuntu kubuntu xubuntu medibuntu blubuntu kravinbuntu
fedora fedora1 fedora2
debian lenny sid
[prema@fedora ~]$ sed 's/\(\w*\ \)/\1\n/g' foo1
ubuntu
kubuntu
xubuntu
medibuntu
blubuntu
kravinbuntu
fedora
fedora1
fedora2
debian
lenny
sid
-
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
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.
$ sed 's:\ :\n:g' /tmp/a | grep -E '^[a-žA-Ž]+'
Pokud
to
není
jedno
slovo
na
řádek
tak
mě
ted
bohužel
nic
nenapadá,
nevím
jak
donutit
v
Bashi
číst
po
to
by
mě
i
do
budoucna
zajímalo
nějakej
způsob.
-
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 :)
-
Ď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ť.
-
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?
-
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.
-
#!/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
-
@Premet
grep při nenelezení řetězce vrací 1, takže test není potřeba
jinak tu evidentně nikdo neřeší existenci interpunkce
#!/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á:
#!/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ší
-
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)?
-
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.
#!/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}
-
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
-
\+ 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.
-
@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
grep -q "\<${line}\>" $2||echo "${line}"
|| za &&
také by nevadilo kdybys ve skriptech používal odsazení :)