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ž…
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…
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…
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…
los 28.10.2013 16:30
los
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?…
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

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:

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