Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno Žádost o pomoc s VBS skripty (vyhledání>nahrazení, uložení do souboru)

Zdar chlapi, chci si v práci ulehčit práci.
Pokouším se vytvořit VBS skript, který by mi ze všech souborů s koncovkou .h(CNC programy) vytahal čísla nástrojů (17 TOOL CALL 112 Z S12000 DR+0
) " \d{3} ", vymazal duplikáty, seřadil je vzestupně pod sebe a uložil do souboru tools.txt do stejné složky. Vypotil jsem toto, ale musím ještě předtím udělat pár úkonů, abych dostal informace do vstupního souboru, z kterého se pak čísla vyexportují, ale už vůbec netuším, jak je seřadit. Já vím, že je tohle prasečina, že se nejdřív vytvoří další soubor a z něj pak až výsledný soubor :-)

Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8

Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objRegEx = CreateObject("VBScript.RegExp")
Set objFile = objFSO.OpenTextFile("a.txt", ForReading)
Set outputfile = objFSO.CreateTextFile("nastroje.txt", True)

objRegEx.IgnoreCase = True
objRegEx.MultiLine = True
objRegEx.Global = True
objRegEx.Pattern = " \d{3} "

Results = ""
Do Until objFile.AtEndOfStream
line = objFile.ReadLine
Set colMatches = objRegEx.Execute(line)
If colMatches.Count > 0 Then
For Each strMatch in colMatches
outputfile.WriteLine strMatch
Next
End If
Loop
objFile.Close


Dim i, j  
 
Set objFSO = CreateObject("Scripting.FileSystemObject") 
Set objInputFile = objFSO.OpenTextFile(".\nastroje.txt", ForReading) 
Set objOutputFile = objFSO.OpenTextFile (WorkingDir & ".\tools.txt", ForWriting, True) 
Set objDict = CreateObject("Scripting.Dictionary") 
j = 0  
'On Error Resume Next 
 
While Not objInputFile.AtEndOfStream 
    arrinputRecord = split(objInputFile.Readline, ",")  
 'Read input file with server names (Split is for later exspantion) 
    strFirstField = arrinputRecord(0)                        
     

    if objDict.Exists(strFirstField) then 
        j=j+1 
    Else 
        objDict.add strFirstField, strFirstField 
    End if 
Wend 
 
colKeys = objDict.Keys 
For Each strKey in colKeys 
    'wscript.echo "Result: " & strKey, objDict.Item(strKey) 
    objOutputFile.writeline objDict.Item(strKey) 
Next 
 
 
objInputFile.Close 
objOutputFile.Close 
 
'Report results 
wscript.Echo "Hotovo, počet duplikátů : " & j 
wscript.Echo "Výsledek v souboru tools.txt "  

Pro spoustu z Vás je to brnkačka, tak bych Vás chtěl požádat, zda byste mi s tím
někdo nepomohl. Už jsem starej pes a než bych se VB naučil a ten skript dokončil,
byl bych v důchodu.
Na zkoušku přikládám pár programů (1.4MB)

S druhým skriptem už jsem totálně v lese. Měl by projet všechny *.h, najít pomocí
regex hodnoty jen v ose Z vyšší, než kterou zadám do vstupního pole a hodnotu přepsat
hodnotou v další vstupním poli. (Mám problém na stroji s tím, že programy jsou generovány
v CAMu a občas se stane, že při vyklonění otočného stolu se nástroj dostane na koncový
spínač, i když v simulaci V CAMu projde vše v pohodě... mašina se zastaví)
S tímhle ani nehnu, tak kdyby to někdo z vás vzal jako výzvu nebo malý úkol na procvičení,
byl bych mu moc vděčný. Kdyby to bylo ve VBS, tak bych si v tom mohl případně něco
málo upravit, nepohrdnu ale ani exe v jakémkoliv jiném jazyce.

24 L M03
25 L B+0.000 C+0.000 FMAX
26 FUNCTION TCPM F TCP AXIS POS PATHCTRL AXIS
27 L M03
28 L Z+42. FMAX
29 L X-16.182 Y-17.499 FMAX
30 L Z+12. FMAX
31 L
32 L X-16.182 Y-17.499 Z+12. FMAX
33 L Z+10.001 FMAX
34 L X-16.182 Y-17.499 Z+5.001 FMAX

Tady je náhled části souboru, tučně jsou zvýrazněny hodnoty, které potřebuji měnit,
zde např. hodnotu od Z+40 výš.
Hodnoty jsou kladná čísla od (+0.001 až +999.999). Regex (určitě by šel i zjednodušit):
Z\+[0-9]?[0-9]?[0-9]?.[0-9]?[0-9]?[0-9]?
Ono by snad i stačilo tohle: Z\+\d. , na jednom milimetru vůbec nezáleží

Předem děkuji převelice každému, kdo mi s tím pomůže.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
VBS mi na to prijde strasne komplikovany, kdybych to mel resit ja (a nemohl to delat na linuxovem st…
gilhad 23.10.2013 01:26
gilhad
cygwin potřeba není, grep i sed jsou pro windows i jako statické binárky. sed.htm grep.htm
touchwood 23.10.2013 06:30
touchwood
Pánové díky moc za snahu, ale tudy asi cesta nepovede. sed i grep jsem nainstaloval, pro jistotu jse…
greyhound 23.10.2013 17:41
greyhound
místo příkazu find (který ve Windows/DOS) funguje jako textový prohledávač je třeba použít příkazu d…
touchwood 23.10.2013 21:36
touchwood
Tohle by taky možná šlo, ale nevím jestli zkouším správně. Pokud napíšu jen tohle bez grepu, neměl b…
greyhound 23.10.2013 21:58
greyhound
možná je tam chyba, psal jsem to zpaměti. viz for /?
touchwood 24.10.2013 06:40
touchwood
Tak jsem se dopracoval jen k vyřešení exportu všech řádků ze všech souborů obsahujících "3číslice oh…
greyhound 24.10.2013 19:53
greyhound
V príkaze sed sa nedajú použiť také konštrukcie, na ktoré si zvyknutý z bežných zápisov (PCRE), takž… nový
los 28.10.2013 14:04
los
Taky moc děkuju :beer:, tohle funguje na výbornou, jen jsem přidal ještě i 4-místné číslo sed -n "s… nový
greyhound 28.10.2013 14:13
greyhound
Měl bych na Tebe jednu otázku ohledně druhého scriptu, kde potřebuju měnit hodnoty v ose Z (pokud je… nový
greyhound 28.10.2013 15:58
greyhound
Keď má sed priamo upravovať súbor, nad ktorým pracuje (prepínač -i), tak si vytvorí dočasný súbor, k… nový
los 28.10.2013 16:30
los
Tučné hodnoty měním scriptem v souboru _start.bat na Z+10. 27 L M03 M07 28 L Z+231.5 FMAX 29 L X+9.… nový
greyhound 28.10.2013 16:37
greyhound
Použil jsem sed z UnxUtils a už je to ok, dělá už jen bak-y. nový
greyhound 28.10.2013 17:18
greyhound
Už vymýšlím blbosti, ale zeptám se: Lze jedním příkazem sed provést více vyhledání na více řádcích?… nový
greyhound 28.10.2013 18:44
greyhound
Pomocou sedu sa dá aj spracovať dva riadky tak, ako si pôvodne chcel: sed -n -e '/.*NASTROJ : /{s//… nový
los 02.11.2013 00:55
los
Dík za pomoc, za celý den vyzkoušel takových věcí a kombinací... až mi vyšlo tohle: for %%i IN (*.h… poslední
greyhound 02.11.2013 23:21
greyhound
První script jsem už "tak nějak" vyřešil, už konečně dělá to co má. Jen jsem přidal do výpisu řádky…
greyhound 28.10.2013 11:29
greyhound
jen technická - samotné regulární výrazy nejsou na 100% stejné ve všech implementacích. Je třeba se…
touchwood 28.10.2013 11:41
touchwood
Díky za pochvalu :-) No právě... že nejsou stejné. Prolezl jsem spoustu stránek ohledně sedu, grepu…
greyhound 28.10.2013 12:22
greyhound
ale druhý skript je VBS, tam musíš použít syntax RegExp kódu VBS. (pokud jsem to pochopil správně)…
touchwood 28.10.2013 12:34
touchwood
Ve VBS je to v pohodě, tuhle syntax tak nějak ovládám, používám ho i na makra v Notepad++ (taky mi t…
greyhound 28.10.2013 12:52
greyhound
a proč jej nezkusíš nahradit jednodušší formou? "[0-9][0-9][0-9] Z"
touchwood 28.10.2013 13:06
touchwood
Teď jsem ještě zkusil z posledních sil zkombinovat pár výrazů, aby aspoň něco sed vzal, vyšlo mi tot… nový
greyhound 28.10.2013 14:05
greyhound
obecně k problematice různých implementací regexpu: http://www.nti.tul.cz/~satrapa/docs/regvyr/all.… nový
touchwood 28.10.2013 16:11
touchwood
Dík za info, konečně pochopitelná stránka v češtině, už je v oblíbených :-) Jdu se vzdělávat nový
greyhound 28.10.2013 16:25
greyhound

VBS mi na to prijde strasne komplikovany, kdybych to mel resit ja (a nemohl to delat na linuxovem stroji), tak si nainstaluju cygwin, cimz ziskam linuxove nastroje (zdarma, legalne).

pak by reseni vypadalo asi takto:

1. priklad - vybrat 3 cislice tvorici cele slovo, seradit a vyhazet duplicity:

find -type f -name "*.h" -exec grep "\<\d{3}\>" {}\;|sed "s/.*\(\<\d{3}\>\).*/\1/"|sort -u>tools.txt

2. priklad:
find -type f -name "*.h" -exec sed -i "s/Z+\([456789]\d|\d{3,}\)\./Z+40./g"

Nevim, jestli vam to k necemu bude, ale pripadne zkuste aspon najit nejake rozumne nastroje na manipulaci textovych souboru, nez to psat vsechno od zacatku

Pánové díky moc za snahu, ale tudy asi cesta nepovede.
sed i grep jsem nainstaloval, pro jistotu jsem je i s knihovnami zkopíroval do adresáře se soubory, které chci projet.
Win příkaz find nepozná parametry v těch příkazových řádcích, nebude on taky součástí Linuxu? A za druhé se v těch přepínačích a parametrech absolutně nevyznám.

Ale úplně mě fascinuje, co jsou lidi schopni nacpat do jednoho řádku :-)

místo příkazu find (který ve Windows/DOS) funguje jako textový prohledávač je třeba použít příkazu dir a příkazu for.

např. výpis všech souborů (ne adresářů) s koncovkou .h z c:\cnc, progrepování a zápis výsledků do soubor.txt

for /f %i IN ('dir /b /a-d c:\cnc\*.h') DO type %i |grep ...a tady si už můžeš grepovat co hrdlo ráčí >>soubor.txt

Tohle by taky možná šlo, ale nevím jestli zkouším správně. Pokud napíšu jen tohle bez grepu, neměl by tenhle
příkaz vlastně zkopírovat obsahy všech .h souborů do jednoho souboru?

for /f %i IN ('dir /b /a-d d:\vbs\el\*.h') DO type %i >>soubor.txt

Pokud ano, tak napíše chybu, že DO nebyl nyní očekáván.

Tak jsem se dopracoval jen k vyřešení exportu všech řádků ze všech souborů obsahujících "3číslice ohraničené mezerami"

15618 TOOL CALL 141 Z S27000 DR+0
47767 TOOL CALL 212 Z S15000 DR+0
60493 TOOL CALL 241 Z S30000 DR+0
280023 TOOL CALL 261 Z S40000 DR+0

for %%i IN (*.h) DO grep -P " \d{3} " %%i |sed "s/.*\(\<\d{3}\>\).*/\1/" >>soubor1.txt

V grepu jsem musel použít přepínač -P, aby mi to bralo tenhle regexp " \d{3} ", gilhadův mi to nebralo vůbec.

Jen ten sed nevím jak zprovoznit, nebere mi to vůbec regulární příkazy nebo je neumím zapsat ve správném formátu.

Linuxový sort jsem našel, ten mi funguje

Jako nouzové řešení beru spustit baťák, v kterém by se vyexportoval temp soubor, který bych prohnal vyvoláním mého VBS scriptu a exportu do souboru, temp soubor pak smazat :-)

PS: za mlada mi říkali zkomoleninou tvýho nicku... Kačůd :-) To ještě skoro nikdo anglicky neuměl :-)

V príkaze sed sa nedajú použiť také konštrukcie, na ktoré si zvyknutý z bežných zápisov (PCRE), takže také \d tam nebude fungovať. Druhá vec je, že ten grep tam už ani nie je potrebný, keď už používaš taký silný nástroj, ako je sed - použiješ prepínač -n a modifikátor /p. Takže namiesto kombinácie grep a sed ti postačí takýto príkaz:

sed -n "s/^.* \([0-9]\{3\}\) .*$/\1/p"

Taky moc děkuju :beer:, tohle funguje na výbornou, jen jsem přidal ještě i 4-místné číslo

sed -n "s/^.* \([0-9]\{3,4\}\) .*$/\1/p"

Jdu zkusit vytvořit novou verzi :-)
Teď už by to mělo jít i bez toho VBS scriptu

EDIT:
No vida :-)

for %%i IN (*.h) DO sed -n "s/^.* \([0-9]\{3,4\}\) .*$/\1\d013_______|______|____________________________|_______________|/p" %%i >>temp1.txt
lsort -g -u temp1.txt > _TOOLS_.txt

Měl bych na Tebe jednu otázku ohledně druhého scriptu, kde potřebuju měnit hodnoty v ose Z (pokud je vyšší než nějaká hodnota, změnit na nižší). Tohle mi tak nějak funguje, jen mi to ke každému vygenerovanému souboru udělá ještě dva další (jeden .bak, druhý nějaký automaticky generovaný název sedxxxxx.)

set a=10
for %%i IN (*.h) DO sed -i.bak "s/ Z+[1-9][0-9][0-9]\./ Z+%a%\./g" %%i

Výraz k vyhledání si budu muset upravovat ručně, k nahrazení stačí proměnná v SET= (vyzkoušeno).
Mohl bys mi s tím pomoci prosím? Nevyznám se moc (skoro vůbec) v přepínačích a modifikátorech, určitě tam mám něco špatně.
Jen potřebuju, aby se hodnota změnila přímo v souboru, případně může udělat soubor záložní.

Děkuji moc

Keď má sed priamo upravovať súbor, nad ktorým pracuje (prepínač -i), tak si vytvorí dočasný súbor, ktorý na konci vymaže. Zrejme počas spracovania spadol a tak po sebe neupratal. Príkaz sed nepoužívam zas tak často, ale na Windowse som s ním na takýto problém ešte nenarazil. Zrejme závisí od vstupov, takže ak sem dáš príklad vstupného súboru a presný príkaz, ktorý si spustil, tak si to môžem u seba otestovať.

Už vymýšlím blbosti, ale zeptám se: Lze jedním příkazem sed provést více vyhledání na více řádcích?
Příklad:
Mám program, z kterého chci vytáhnout číslo nástroje T a za něj doplnit info o nástroji (112 D=12.00 R=1.00 (d12R1-l55-Kieninger))

13 ; PROGRAM NA : Spicka NASTROJE
14 ; NASTROJ : D=12.00 R=1.00 (d12R1-l55-Kieninger)
15 ; PRIDAVEK : P=0.500
16 ;*****************************************
17 TOOL CALL 112 Z S12000 DR+0

for %%i IN (*.h) DO sed -n "s/^.*NASTROJ    : \(.*$\)^.* \([0-9]\{3,4\}\) Z.*$/\2 \1/p" %%i >>temp1.txt

Oba výrazy text najdou, ale jen každý zvlášť
^.*NASTROJ : \(.*$\)
^.* \([0-9]\{3,4\}\) Z.*$
Jde to nějak ošetřit, aby nalezl najednou oba výrazy a zapsal je do jednoho řádku?

...jsou to kouzla a čáry...

EDIT: Tak na to kašlu, zjistil jsem, že když je pro jeden nástroj více drah, tak už se v programu nevyskytuje volání nástroje, je tam jen popis. Musely by být splněny obě podmínky najednou (např.když najde popis, musí do 3.řádku najít ještě číslo nástroje. Pro mě nemyslitelné, vzdávám to :-)

Ještě jednou moc díky všem poradcům za rady a hlavně trpělivost :-)

Pomocou sedu sa dá aj spracovať dva riadky tak, ako si pôvodne chcel:

sed -n -e '/.*NASTROJ : /{s///;h}' -e '/.*\([0-9]\{3,4\}\) Z.*/{s//\1/;H;g;s/\n/ /;p}'

Prvý výraz:

/.*NASTROJ : /  - nájde riadok s textom NASTROJ, pričom výraz zachytí text po dvojbodku s medzerou
{
  s///;  - nahradí zachytený text za prázdny reťazec
  h      - odloží výsledok
}

Druhý výraz:

/.*\([0-9]\{3,4\}\) Z.*/  - nájde riadok s 3-4 číslicami nasledovanými písmenom Z, pričom zachytí celý riadok
{
  s//\1/;   - nahradí zachytený text za tie 3-4 číslice
  H;        - pridá výsledok na nový riadok k už odloženému výsledku
  g;        - vyberie odložený výsledok (dva riadky)
  s/\n/ /;  - nahradí znak nového riadku za medzeru
  p         - vypíše výsledok
}

So sedom sa dá toho robiť naozaj veľa.

Edit: Aha, ty si to chcel vlastne v opačnom poradí. Tak potom takto:

sed -n -e '/.*NASTROJ : /{s///;h}' -e '/.*\([0-9]\{3,4\}\) Z.*/{s//\1/;G;s/\n/ /;p}'

Dík za pomoc, za celý den vyzkoušel takových věcí a kombinací... až mi vyšlo tohle:

for %%i IN (*.h) DO sed -n -e "/.*NASTROJ    : \(.*$\)/{s//\1/;h}" -e "/.* \([0-9]\{3,4\}\) Z.*$/{s//\1 \|  /;G;s/\n/ /;p}" %%i >> vystup.txt
lsort -u vystup.txt > _TOOLS_.txt

Výstup vypadá takhle:

112 | D=12.00 R=1.00 (d12R1-l55-Kieninger)
115 | D=6.00 R=3.00 (d6R3-L40-Kieninger)
136 | D=4.00 R=0.50 (d4R0,5-d4 v delce 40 celkem vylozeno 50 - WEDCO)
212 | D=12.00 R=1.00 (d12R1-l55-Kieninger)
.
.
.

Ještě si pohraju s formátováním aby mi to sedělo do tabulky a bude to přesně jak jsem potřeboval.
Sice to vůbec nechápu, ale hlavní je, že to chodí tak jak má :-)

Tisíceré díky, moc jsi mi pomohl :beer::beer::beer:

První script jsem už "tak nějak" vyřešil, už konečně dělá to co má. Jen jsem přidal do výpisu řádky s podtržítky a svislítky, aby se na papír mohlo psát většími písmeny. Kdybych měl čísla jen pod sebou tak bych použil jen cut místo sed. Už do toho začínám trochu pronikat, mám o zábavu na dlouhou dobu postaráno.

Tohle je výpis, takhle mi to vyhovuje:

 112 
_______|______|____________________________|_______________|
 115 
_______|______|____________________________|_______________|
 1153 
_______|______|____________________________|_______________|
 1157 
_______|______|____________________________|_______________|
 1191 
_______|______|____________________________|_______________|

Akorát sed nerozumí mým regulárním výrazům, ať to zkouším jak to zkouším :-) Zkoušel jsem testovat výrazy v RegexBuddy, ale pro GNU nejspíš neplatí jako zástupný znak pro číslici \d . Zkoušel jsem v sed-u psí kusy, ale stejně se nepovedlo. Není potřeba nějaká externí dll?

Jinak Vám dvěma moc děkuju, bez Vás bych to dohromady nedal :beer::beer:

EDIT: oprava, ve _start.bat má být (@lsort -g -u)

Díky za pochvalu :-)
No právě... že nejsou stejné. Prolezl jsem spoustu stránek ohledně sedu, grepu a reg.výrazů, moc chytrý jsem z toho nebyl. Sed používám ten z Tvého odkazu, ještě zkusím z UnxUtil nebo Cygwinu, třeba se nějaký chytne. Ty regulární výrazy bych potřeboval rozchodit kvůli vyřešení druhého scriptu, tam je opravdu potřebovat budu. Zatím musím vydejchat ten první :-)

Ve VBS je to v pohodě, tuhle syntax tak nějak ovládám, používám ho i na makra v Notepad++ (taky mi tedy dává občas zabrat :-)). Hledám řetězec, který začíná mezerou, pak je 3až4-ciferné číslo, mezera a Z. To Z tam mám kvůli pozdější náhradě za nový řádek "náznak tabulky".

I ten grep, když mu dám parametr -P tak mi " \d{3,4} Z" vezme a řetězec najde.
Jen ten zatrsakr sed ne :-) Ona je spousta příkladů jak sed použít, bohužel většina jen při práci s textem. Už mi z toho občas hrábě :-)

Teď jsem ještě zkusil z posledních sil zkombinovat pár výrazů, aby aspoň něco sed vzal, vyšlo mi toto:

sed -r s/" [0-9]? ?[0-9][0-9][0-9] Z"/test/ soubor1.txt >s.txt

"mezera,číslo 100-1999,mezera,Z" nahradit řetězcem test. Akorát bych potřeboval nahradit vše ostatní kromě nalezeného výrazu. Ještě si s tim budu muset hodně pohrát a pochopit.
Tu mezeru na začátku taky potřebuju, jinak mi to najde i tohle (L X-0.224 Y+1.939 Z+11.437 B+1.889 C+96.618).
Ten sed využiju v druhém scriptu, tam už musím řetězec nahrazovat, tohle byl jen test.

Zpět do poradny Odpovědět na původní otázku Nahoru