Correct BCP syntax - windows

I am a first time BCP user. I have an XML file that I need to import into a new table in SQL Server. This is using SQL Server 2008 and BCP version 10.50.16. I read through the documentation but I get 370,000 errors! (This is a very large file). When I open the error log, I just see a bunch of question marks.
About this XML file: it does use a new line to delineate rows, however, it uses the space character to separate fields. So I'm not sure if that is what causes it to fail. The failure message is:
BCP copy in failedI wish it were more descriptive. Is there a way to get a more detailed error message?
Otherwise, here is my command:
d:\SQL Tables\data>bcp Development.dbo.wbl_zSkywardEnrollment2 in zSkywardEnroll
ment.xml -fSE_format.fmt -m50 -eseErrorLog -b100 -t0x20 -T -F107
All of these files are in this same directory. I know it says to specify full file path, but since they're all in this same directory and also I saw another example where they didn't specify directories I thought this would suffice.
I have tried this without the format file also, doing it interactively but get same errors.
This is my format file:
10.0
32
1 SQLINT 0 4 " " 1 SCHOOL_YEAR ""
2 SQLNCHAR 2 20 " " 2 ENTITY_ID SQL_Latin1_General_CP1_CI_AS
3 SQLINT 0 4 " " 3 TERM_NBR ""
4 SQLINT 1 4 " " 4 SCHD_HST_GRAD_YEAR ""
5 SQLNCHAR 2 60 " " 5 OTHER_ID SQL_Latin1_General_CP1_CI_AS
6 SQLNUMERIC 1 19 " " 6 GRAD_YR ""
7 SQLNCHAR 2 120 " " 7 LAST_NAME SQL_Latin1_General_CP1_CI_AS
8 SQLNCHAR 2 60 " " 8 FIRST_NAME SQL_Latin1_General_CP1_CI_AS
9 SQLNCHAR 2 60 " " 9 MIDDLE_NAME SQL_Latin1_General_CP1_CI_AS
10 SQLDATETIME 1 8 " " 10 BIRTHDATE ""
11 SQLNCHAR 2 4 " " 11 GENDER SQL_Latin1_General_CP1_CI_AS
12 SQLNCHAR 2 20 " " 12 RACE_CODE SQL_Latin1_General_CP1_CI_AS
13 SQLNCHAR 2 40 " " 13 DISTRICT_CODE SQL_Latin1_General_CP1_CI_AS
14 SQLBIT 1 1 " " 14 X_SPECIAL_EDUCATION ""
15 SQLBIT 1 1 " " 15 X_GIFTED_TALENTED ""
16 SQLBIT 1 1 " " 16 X_SECTION_504 ""
17 SQLBIT 1 1 " " 17 X_MIGRANT ""
18 SQLBIT 1 1 " " 18 X_IEP ""
19 SQLBIT 1 1 " " 19 X_IEP_ACCOM ""
20 SQLBIT 1 1 " " 20 X_ESL ""
21 SQLNCHAR 2 4 " " 21 STUDENT_STATUS SQL_Latin1_General_CP1_CI_AS
22 SQLINT 0 4 " " 22 STUDENT_ID ""
23 SQLINT 1 4 " " 23 ENG_PROF ""
24 SQLNCHAR 2 60 " " 24 ALPHAKEY SQL_Latin1_General_CP1_CI_AS
25 SQLNCHAR 2 20 " " 25 SCHOOL_ID SQL_Latin1_General_CP1_CI_AS
26 SQLNUMERIC 1 19 " " 26 MN_EDE_NBR ""
27 SQLNCHAR 2 20 " " 27 LANGUAGE_CODE SQL_Latin1_General_CP1_CI_AS
28 SQLINT 1 4 " " 28 ADVISOR ""
29 SQLBIT 1 1 " " 29 MN_LIMITED_ENGLISH ""
30 SQLNCHAR 2 20 " " 30 TYPE_STUDENT_ID SQL_Latin1_General_CP1_CI_AS
31 SQLNCHAR 2 20 " " 31 CY_TEAM_SCHD_ID SQL_Latin1_General_CP1_CI_AS
32 SQLNCHAR 2 20 " " 32 HOMEROOM_NUMBER SQL_Latin1_General_CP1_CI_AS
This is my SQL table:
CREATE TABLE [dbo].[wbl_zSkywardEnrollment2](
[SCHOOL_YEAR] [int] NOT NULL,
[ENTITY_ID] [nvarchar](10) NOT NULL,
[TERM_NBR] [int] NOT NULL,
[SCHD_HST_GRAD_YEAR] [int] NULL,
[OTHER_ID] [nvarchar](30) NULL,
[GRAD_YR] numeric(19,0) NULL,
[LAST_NAME] [nvarchar](60) NOT NULL,
[FIRST_NAME] [nvarchar](30) NULL,
[MIDDLE_NAME] [nvarchar](30) NULL,
[BIRTHDATE] datetime NULL,
[GENDER] [nvarchar](2) NULL,
[RACE_CODE] [nvarchar](10) NULL,
[DISTRICT_CODE] [nvarchar](20) NULL,
[X_SPECIAL_EDUCATION] bit NULL,
[X_GIFTED_TALENTED] bit NULL,
[X_SECTION_504] bit NULL,
[X_MIGRANT] bit NULL,
[X_IEP] bit NULL,
[X_IEP_ACCOM] bit NULL,
[X_ESL] bit NULL,
[STUDENT_STATUS] [nvarchar](2) NULL,
[STUDENT_ID] [int] NOT NULL,
[ENG_PROF] [int] NULL,
[ALPHAKEY] [nvarchar](30) NOT NULL,
[SCHOOL_ID] [nvarchar](10) NULL,
[MN_EDE_NBR] [numeric](19, 0) NULL,
[LANGUAGE_CODE] [nvarchar](10) NULL,
[ADVISOR] [int] NULL,
[MN_LIMITED_ENGLISH] bit NULL,
[TYPE_STUDENT_ID] [nvarchar](10) NULL,
[CY_TEAM_SCHD_ID] [nvarchar](10) NULL,
[HOMEROOM_NUMBER] [nvarchar](10) NOT NULL
) ON [PRIMARY]
And I have tried this starting with row 1. I am curious which line should BCP start on? Line 1 of this XML starts with Schema and ElementType info. But on line 107 is where rs:data section starts.
The first part of this XML file:
<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
xmlns:rs='urn:schemas-microsoft-com:rowset'
xmlns:z='#RowsetSchema'>
<s:Schema id='RowsetSchema'>
<s:ElementType name='row' content='eltOnly'>
<s:AttributeType name='c0' rs:name='SCHOOL_YEAR' rs:number='1'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c1' rs:name='ENTITY_ID' rs:number='2'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='10' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c2' rs:name='TERM_NBR' rs:number='3'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c3' rs:name='SCHD_HST_GRAD_YEAR' rs:number='4' rs:nullable='true'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c4' rs:name='OTHER_ID' rs:number='5' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='24'/>
</s:AttributeType>
<s:AttributeType name='c5' rs:name='GRAD_YR' rs:number='6' rs:nullable='true'>
<s:datatype dt:type='number' rs:dbtype='numeric' dt:maxLength='19' rs:scale='0' rs:precision='15' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c6' rs:name='LAST_NAME' rs:number='7'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='60' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c7' rs:name='FIRST_NAME' rs:number='8' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='30'/>
</s:AttributeType>
<s:AttributeType name='c8' rs:name='MIDDLE_NAME' rs:number='9' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='30'/>
</s:AttributeType>
<s:AttributeType name='BIRTHDATE' rs:name='BIRTHDATE' rs:number='10' rs:nullable='true' rs:write='true'>
<s:datatype dt:type='date' dt:maxLength='6' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='GENDER' rs:name='GENDER' rs:number='11' rs:nullable='true' rs:write='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='2'/>
</s:AttributeType>
<s:AttributeType name='c11' rs:name='RACE_CODE' rs:number='12' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='6'/>
</s:AttributeType>
<s:AttributeType name='c12' rs:name='DISTRICT_CODE' rs:number='13' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='14'/>
</s:AttributeType>
<s:AttributeType name='c13' rs:name='X_SPECIAL_EDUCATION' rs:number='14' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c14' rs:name='X_GIFTED_TALENTED' rs:number='15' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c15' rs:name='X_SECTION_504' rs:number='16' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c16' rs:name='X_MIGRANT' rs:number='17' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c17' rs:name='X_IEP' rs:number='18' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c18' rs:name='X_IEP_ACCOM' rs:number='19' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c19' rs:name='X_ESL' rs:number='20' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c20' rs:name='STUDENT_STATUS' rs:number='21' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='2'/>
</s:AttributeType>
<s:AttributeType name='c21' rs:name='STUDENT_ID' rs:number='22'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c22' rs:name='ENGL_PROF' rs:number='23' rs:nullable='true'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='ALPHAKEY' rs:name='ALPHAKEY' rs:number='24' rs:write='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='22' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c24' rs:name='SCHOOL_ID' rs:number='25'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='10' rs:maybenull='false'/>
</s:AttributeType>
<s:AttributeType name='c25' rs:name='MN_EDE_NBR' rs:number='26' rs:nullable='true'>
<s:datatype dt:type='number' rs:dbtype='numeric' dt:maxLength='19' rs:scale='0' rs:precision='15' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c26' rs:name='LANGUAGE_CODE' rs:number='27' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='6'/>
</s:AttributeType>
<s:AttributeType name='c27' rs:name='ADVISOR' rs:number='28' rs:nullable='true' rs:write='true'>
<s:datatype dt:type='int' dt:maxLength='4' rs:precision='10' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c28' rs:name='MN_LIMITED_ENGLISH' rs:number='29' rs:nullable='true'>
<s:datatype dt:type='boolean' dt:maxLength='2' rs:fixedlength='true'/>
</s:AttributeType>
<s:AttributeType name='c29' rs:name='TYPE_STUDENT_ID' rs:number='30' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='6'/>
</s:AttributeType>
<s:AttributeType name='c30' rs:name='CY_TEAM_SCHD_ID' rs:number='31' rs:nullable='true'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='6'/>
</s:AttributeType>
<s:AttributeType name='c31' rs:name='HOMEROOM_NUMBER' rs:number='32'>
<s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='10' rs:maybenull='false'/>
</s:AttributeType>
<s:extends type='rs:rowbase'/>
</s:ElementType>
</s:Schema>
<rs:data>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>
<z:row c0='2004' c1='057' c2='0' c3='2010' c4='671590' c5='2010' c6='AANENSON' c7='SHELLI' c8='A' BIRTHDATE='1992-07-01'
GENDER='F' c11='5' c12='' c13='False' c14='True' c15='False' c16='False' c17='False' c18='False' c19='False'
c20='I' c21='12' c22='7' ALPHAKEY='AANENSHE000' c24='057' c25='624000671590' c26='011' ADVISOR='0' c28='False'
c29='R' c30='' c31=''/>

You can't use bcp for this. The best that bcp can give you is an import from a file with comma/tab/etc. separated values. All references that you see to xml in the bcp documentation refer to the format file, not to the actual data to import.
There are actually two ways of doing this. The easiest is to use SQL Server Integration Services for this. This can help you further.
You could also do this by reading the xml file into SQL server. Then use sp_xml_preparedocument to parse the file. Finally, use OPENXML in combination with INSERT to import the data.

Related

How to avoid interepretation of string as command in CMD?

I have code which get PNPDeviceID of Videocard currently installed in system
FOR /F %i IN ('wmic path win32_VideoController get PNPdeviceid ^| findstr _') DO (SET fd="%i")
echo %fd%
C:\Users\user>echo %fd:~1,-1%
PCI\VEN_10DE
"DEV_0641" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
"SUBSYS_00000000" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
Системе не удается найти указанный путь.
"1A8B4BFC" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
"0" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
"0008" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
When I try to display value of fd variable CMD interpret value of variable as chan of commands and try to execute it. Can I somehow avoid it? Because I need to store only part of this variable, but when i try to do it I recieve error message.
I understand that CMD see & sign and try to interpret it as command operator
Use echo "%fd%" instead of echo %fd%. Doublequotes preserve cmd.exe from interpreting & as a command chaining character.

Single and Double Quote Issue using GAWK

I have been helped with the following GAWK command line in Windows
gawk "{a = gensub(/([0-9]{6} [0-9]{6} [0-9]{4}).*itemId=, "\\2 \\1", "g", $0); b = split(a, c, " "); if (c[1] in result) result[c[1]] = gensub(/(.+),(.+)/, "\\1," c[2] " " c[3] " " c[4], "g", result[c[1]]); else result[c[1]] = c[2] " " c[3] " " c[4] "," c[2] " " c[3] " " c[4]} END { for (i in result) print i ": " result[i]}" Item.log
I have thousands of lines of text, like below which contain information for an item in ITEMID, these can be spread throughout the file, I want to get the first date and time and the last date and time and create a line like :
ITEMID 170209 003122 170209 003621
The date format about is YYMMDD HHMMSS
170209 003122 0893 DE(N) ItemHandler.ItemLog event=<VOLUME_RESULT>, *************************, itemId=<12551677>, globalId=<12551677>, cmcIndex=<973>, sorter=<0: MS01>, state=<CSC: WaitForData>, volumeId=<4104: MS01.IU05-VMS04>, volumeStatus=<0>, volScanResult=<0>, length=<665 mm>, width=<610 mm>, height=<470 mm>, volume=<190656000 mm3>, position=<sorter#0.volume#4104: MS01.IU05-VMS04>, volSystemId=<4>, volReferenceRecord=<2542>, volLevelOffset=<0>, volDataCrc=<48107>, itemRevisionNumber=<3> ##[
170209 003126 0210 DE(N) ItemHandler.ItemLog event=<SCANNER_RESULT>, ************************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForData>, barcodeCount=<1>, barcodes=<[ProxyWrapperBarcode(barcode=<T000042357>, type=<C0>, result=<OK>, ccType=<>)]>, codeSource=<ohscan>, scannerId=<4000: SCAN01>, scannerStatus=<0>, position=<sorter#0.scanner#4000: SCAN01>, itemRevisionNumber=<5> ##[
170209 003126 0210 DE(N) ItemHandler.ItemLog event=<DESTINATION_REQUEST>, *******************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForData>, barcodes=<[ProxyWrapperBarcode(barcode=<T000042357>, type=<C0>, result=<OK>, ccType=<>)]>, ccReason=<SCANNER_DATA_ADDED>, PreviousccResult=<>, sortSchemeId=<-1>, sortSchemeName=<>, logicalDestination=<>, BatchCountItem=<true>, collectionId=<-1>, goodsId=<>, position=<sorter#0.scanner#4000: SCAN01>, dynamicDataCount=<0>, dynamicData=<{}>, carrierId=<202>, carrierCount=<1>, itemRevisionNumber=<5> ##[
170209 003126 0225 DE(N) ItemHandler.ItemLog event=<DESTINATION_REPLY>, *********************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, ccReason=<SCANNER_DATA_ADDED>, PendingccResult=<OK>, Pendingstrategy=<notSpecified>, PendingchuteGroup=<[3000]: Parked0>, PendingNotChutedestinationId=<-1>, PendingsortSchemeId=<-1>, PendingsortSchemeName=<>, PendinglogicalDestination=<>, PendinggoodsId=<>, PendingBatchCountItem=<true>, PendingcollectionId=<-1>, position=<sorter#0.scanner#4000: SCAN01>, dynamicDataCount=<0>, dynamicData=<{}>, itemRevisionNumber=<7> ##[
170209 003126 0225 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM>, *************************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, PendingchuteGroup=<[3000]: Parked0>, Pendingstrategy=<notSpecified>, CscdestinationId=<-1: UnDef>, CmcdestinationId=<4099: All Scanners>, position=<sorter#0.scanner#4000: SCAN01>, itemRevisionNumber=<7> ##[
170209 003126 0454 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM_REPLY>, *******************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, CscdestinationId=<3000: Parked0>, chuteGroup=<[3000]: Parked0>, CmcdestinationId=<3000: Parked0>, position=<sorter#0.scanner#4000: SCAN01>, chuteListStartPoint=<-1>, itemRevisionNumber=<9> ##[
170209 003126 0456 DE(N) ItemHandler.ItemLog event=<RECONVERT>, *****************************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForData>, CscdestinationId=<3000: Parked0>, chuteGroup=<[3000]: Parked0>, CmcdestinationId=<3000: Parked0>, position=<sorter#0.scanner#4000: SCAN01>, chuteListStartPoint=<-1>, itemRevisionNumber=<10> ##[
170209 003126 0456 DE(N) ItemHandler.ItemLog event=<DESTINATION_REQUEST>, *******************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForData>, barcodes=<[ProxyWrapperBarcode(barcode=<T000042357>, type=<C0>, result=<OK>, ccType=<>)]>, ccReason=<SCANNER_DATA_ADDED>, PreviousccResult=<OK>, sortSchemeId=<-1>, sortSchemeName=<>, logicalDestination=<>, BatchCountItem=<true>, collectionId=<-1>, goodsId=<>, position=<sorter#0.scanner#4000: SCAN01>, dynamicDataCount=<0>, dynamicData=<{}>, carrierId=<202>, carrierCount=<1>, itemRevisionNumber=<10> ##[
170209 003126 0458 DE(N) ItemHandler.ItemLog event=<DESTINATION_REPLY>, *********************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, ccReason=<SCANNER_DATA_ADDED>, PendingccResult=<OK>, Pendingstrategy=<priority>, PendingchuteGroup=<[186, 188, 195, 201, 184]: [XRA502, XRA503, XRA605, XRA607, XRA501]>, PendingNotChutedestinationId=<-1>, PendingsortSchemeId=<-1>, PendingsortSchemeName=<>, PendinglogicalDestination=<XRA502>, PendinggoodsId=<>, PendingBatchCountItem=<true>, PendingcollectionId=<-1>, position=<sorter#0.scanner#4000: SCAN01>, dynamicDataCount=<0>, dynamicData=<{}>, itemRevisionNumber=<12> ##[
170209 003126 0458 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM>, *************************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, PendingchuteGroup=<[186, 188, 195, 201, 184]: [XRA502, XRA503, XRA605, XRA607, XRA501]>, Pendingstrategy=<priority>, CscdestinationId=<3000: Parked0>, CmcdestinationId=<3000: Parked0>, position=<sorter#0.scanner#4000: SCAN01>, itemRevisionNumber=<12> ##[
170209 003126 0681 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM_REPLY>, *******************, itemId=<12551674>, globalId=<12551674>, cmcIndex=<970>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, CscdestinationId=<186: XRA502>, chuteGroup=<[186, 188, 195, 201, 184]: [XRA502, XRA503, XRA605, XRA607, XRA501]>, CmcdestinationId=<186: XRA502>, position=<sorter#0.scanner#4000: SCAN01>, chuteListStartPoint=<186>, itemRevisionNumber=<14> ##[
170209 003126 0981 DE(N) ItemHandler.ItemLog event=<ITEM_INDUCTED>, *************************, itemId=<12551677>, globalId=<12551677>, cmcIndex=<973>, sorter=<0: MS01>, state=<CSC: WaitForData>, inductionId=<4: IU05>, inductionMode=<SCANNER>, inductStatus=<NORMAL_ITEM>, carrierId=<343>, carrierCount=<1>, CmcdestinationId=<4099: All Scanners>, position=<sorter#0: MS01>, itemRevisionNumber=<4> ##[
170209 003129 0845 DE(N) ItemHandler.ItemLog event=<ITEM_AT_INDUCTION>, *********************, itemId=<12551678>, globalId=<12551678>, cmcIndex=<974>, sorter=<0: MS01>, state=<CSC: ProjectIdle>, inductionId=<4: IU05>, position=<sorter#0.induction#4: IU05>, itemRevisionNumber=<0> ##[
170209 003129 0845 DE(N) ItemHandler.ItemLog event=<SET_ITEM_ID>, ***************************, itemId=<12551678>, globalId=<12551678>, cmcIndex=<974>, sorter=<0: MS01>, state=<CSC: ProjectIdle>, itemRevisionNumber=<0> ##[
170209 003130 0027 DE(N) ItemHandler.ItemLog event=<ITEM_PASSED_SPS>, ***********************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: ProjectHeadingForChute>, carrierId=<363>, carrierCount=<1>, CmcdestinationId=<198: EXP507>, CscdestinationId=<198: EXP507>, itemRevisionNumber=<15> ##[
170209 003130 0350 DE(N) ItemHandler.ItemLog event=<DISCHARGE_ATTEMPTED>, *******************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: ProjectHeadingForChute>, CscdestinationId=<198: EXP507>, chuteGroup=<[198]: EXP507>, CmcdestinationId=<198: EXP507>, position=<sorter#0: MS01>, itemRevisionNumber=<15> ##[
170209 003130 0352 DE(N) ItemHandler.ItemLog event=<RECONVERT>, *****************************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: ProjectHeadingForChute>, CscdestinationId=<198: EXP507>, chuteGroup=<[198]: EXP507>, CmcdestinationId=<198: EXP507>, position=<sorter#0: MS01>, chuteListStartPoint=<198>, itemRevisionNumber=<16> ##[
170209 003130 0352 DE(N) ItemHandler.ItemLog event=<DESTINATION_REQUEST>, *******************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: ProjectHeadingForChute>, barcodes=<[ProxyWrapperBarcode(barcode=<3709160626>, type=<A0>, result=<OK>, ccType=<>), ProxyWrapperBarcode(barcode=<2LIN400023+48000001>, type=<C0>, result=<OK>, ccType=<>)]>, ccReason=<SCANNER_DATA_ADDED>, PreviousccResult=<OK>, sortSchemeId=<-1>, sortSchemeName=<>, logicalDestination=<EXP507>, BatchCountItem=<true>, collectionId=<-1>, goodsId=<>, position=<sorter#0: MS01>, dynamicDataCount=<1>, dynamicData=<{VID=2017020905551665}>, carrierId=<363>, carrierCount=<1>, itemRevisionNumber=<16> ##[
170209 003130 0354 DE(N) ItemHandler.ItemLog event=<DESTINATION_REPLY>, *********************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, ccReason=<SCANNER_DATA_ADDED>, PendingccResult=<OK>, Pendingstrategy=<notSpecified>, PendingchuteGroup=<[3000]: Parked0>, PendingNotChutedestinationId=<-1>, PendingsortSchemeId=<-1>, PendingsortSchemeName=<>, PendinglogicalDestination=<>, PendinggoodsId=<>, PendingBatchCountItem=<true>, PendingcollectionId=<-1>, position=<sorter#0: MS01>, dynamicDataCount=<1>, dynamicData=<{VID=2017020905551665}>, itemRevisionNumber=<18> ##[
170209 003130 0354 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM>, *************************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, PendingchuteGroup=<[3000]: Parked0>, Pendingstrategy=<notSpecified>, CscdestinationId=<198: EXP507>, CmcdestinationId=<198: EXP507>, position=<sorter#0: MS01>, itemRevisionNumber=<18> ##[
170209 003130 0517 DE(N) ItemHandler.ItemLog event=<REDIRECT_ITEM_REPLY>, *******************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: WaitForDestination>, CscdestinationId=<3000: Parked0>, chuteGroup=<[3000]: Parked0>, CmcdestinationId=<3000: Parked0>, position=<sorter#0: MS01>, chuteListStartPoint=<198>, itemRevisionNumber=<20> ##[
170209 003130 0520 DE(N) ItemHandler.ItemLog event=<RECONVERT>, *****************************, itemId=<12551665>, globalId=<12551665>, cmcIndex=<961>, sorter=<0: MS01>, state=<CSC: WaitForData>, CscdestinationId=<3000: Parked0>, chuteGroup=<[3000]: Parked0>, CmcdestinationId=<3000: Parked0>, position=<sorter#0: MS01>, chuteListStartPoint=<198>, itemRevisionNumber=<21> ##[
The issue I have is that I can't get the above command line to work because of the issues around single and double quotes when I run it in a windows batch file in DOS, I have other gawk commands working but they use " double quotes can anyone help
Thanks
Phil
Getting quotes and sometimes other special characters correctly through Windows commandline is frequently hard, especially with programs designed for Unix like gawk because there are several different methods of porting Unix-based or otherwise non-Windows C programs to the multiple subtly different implementations of C (or C++) on Windows.
A usually better approach for awk (and perl) in particular is to put the script in a file, something like this, which also allows you to use linebreaks to format it better:
myscript.awk:
{a = gensub(/([0-9]{6} [0-9]{6} [0-9]{4}).*itemId=, "\\2 \\1", "g", $0);
b = split(a, c, " ");
if (c[1] in result) result[c[1]] = gensub(/(.+),(.+)/, "\\1," c[2] " " c[3] " " c[4], "g", result[c[1]]);
else result[c[1]] = c[2] " " c[3] " " c[4] "," c[2] " " c[3] " " c[4] }
END { for (i in result) print i ": " result[i] }
then
gawk -f myscript.awk item.log
PS: your first gensub is clearly missing its closing / presumably after itemId= but even with that change it makes little sense because you have only one capture group but you specify a replacement string that uses two. Conversely your second gensub (the one in the if branch) has two capture groups but uses only one. Please check back with whoever 'helped' you.

rspec giving undefined method

RSpec noob needs help. My brain is mush right now...I'm trying to create a basic "I exist and I return a value" set of test for this method in my code...
def attempt_win(board)
#ai_winmoves.each do |k, v| # go through each win move in the ai_winmoves array located above.
ai_keys = v.select{ |k, v| v == "O"}.keys # grab all computer player's Os from the value hash
intersection = ai_keys & #keys_with_o # get common elements between two arrays..note: keys_with_o = all current O's on game board
if intersection.length >=2 # when two intersections exist it means two O's are on the board
#answers_array << k # add to answers array per iteration
#answers_array.each do |key|
# answer = #anskey[#thing.last].to_sym
puts "which moves can ai win with?"
puts #anskey[key]
answer = #anskey[key].to_sym
puts "attempt win"
puts answer
if board.grid[answer] == " " #if win move space is empty take it
#move = answer
else #check for a block move
# attempt_block # handled at line 162
end
end
end
end # END #ai_winmoves.each do |k,v|
end
Here is my test code...
describe 'attempt_win' do
before (:each) do
#board.grid[:b2] == "X"
end
xit 'computer looks for any possible win move'
it 'computer returns a value' do
#player_computer.attempt_win(#board).should_not be(nil)
end
end
here is the rspec failure I'm getting...
1) Player class attempt_win computer returns a value
Failure/Error: #player_computer.attempt_win(#board).should_not be(nil)
NoMethodError:
undefined method `each' for nil:NilClass
# ./lib/player.rb:171:in `attempt_win'
# ./spec/player_spec.rb:47:in `block (3 levels) in <top (required)>'
THAT'S IT BUT.....
IF YOU WANT TO SEE THE ENTIRE CLASS FILE player.rb and it's test file player_spec.rb LOOK BELOW...
# TODO - send error output if move already taken
# TODO - better WIN detection
class Player
attr_reader :boardpiece # i exist so game.rb can read me
def initialize(letter)
#boardpiece = letter
end
def move_human(game, board)
#game_two = game
puts "human move..."
human_move = gets.chomp
human_symbol = human_move.to_sym
# look for move as key in board.grid
if board.grid.has_key?(human_symbol)
if board.grid[human_symbol] == " "
#puts "bingo"
#move = human_symbol
else
puts "spot taken...try again"
move_human(#game_two, board)
end
else
puts "invalid move...try again"
move_human(#game_two, board)
end
end
def move_computer(game, board)
# ai should do three things
# attempt win
# block human
# random move
puts "computer move..."
# all possible third moves as 'O' (computer)
#human_winmoves = {
:wm01 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm02 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm03 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm04 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm05 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm06 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>" "},
:wm07 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm08 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"X", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"X"},
#check those corners
:wm09 => {:a1=>"X", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm10 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm11 => {:a1=>" ", :a2=>"X", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm12 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm13 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>"X"},
:wm14 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>"X"},
:wm15 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>"X", :c3=>" "},
:wm16 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>" "},
#check opposites
:wm17 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>" "},
:wm18 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm19 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"X"},
:wm20 => {:a1=>"X", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm21 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm22 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"X"},
:wm23 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>"X"},
:wm24 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>" "},
#check crazy
:wm25 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"X", :c2=>" ", :c3=>" "},
:wm26 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm27 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"X"},
:wm28 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm29 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm30 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm31 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm32 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>"X", :c3=>" "},
:wm33 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm34 => {:a1=>" ", :a2=>" ", :a3=>"X", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm35 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"X", :c3=>" "},
:wm36 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"X", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"X"},
:wm37 => {:a1=>"X", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm38 => {:a1=>" ", :a2=>"X", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>" ", :c3=>" "},
:wm39 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>"X", :c2=>" ", :c3=>" "},
:wm40 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"X", :c1=>" ", :c2=>"X", :c3=>" "}
}
#ai_winmoves = {
:wm01 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm02 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm03 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm04 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm05 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm06 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
:wm07 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm08 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>"O", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
#check those corners
:wm09 => {:a1=>"O", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm10 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm11 => {:a1=>" ", :a2=>"O", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm12 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm13 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>"O"},
:wm14 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>"O"},
:wm15 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>"O", :c3=>" "},
:wm16 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
#check opposites
:wm17 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
:wm18 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm19 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
:wm20 => {:a1=>"O", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm21 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm22 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
:wm23 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>"O"},
:wm24 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
#check crazy
:wm25 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>"O", :c2=>" ", :c3=>" "},
:wm26 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm27 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
:wm28 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm29 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm30 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm31 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>" ", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm32 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>"O", :c3=>" "},
:wm33 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm34 => {:a1=>" ", :a2=>" ", :a3=>"O", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>" "},
:wm35 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>"O", :c3=>" "},
:wm36 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>"O", :b2=>" ", :b3=>" ", :c1=>" ", :c2=>" ", :c3=>"O"},
:wm37 => {:a1=>"O", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm38 => {:a1=>" ", :a2=>"O", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>" ", :c3=>" "},
:wm39 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>"O", :c2=>" ", :c3=>" "},
:wm40 => {:a1=>" ", :a2=>" ", :a3=>" ", :b1=>" ", :b2=>" ", :b3=>"O", :c1=>" ", :c2=>"O", :c3=>" "}
}
# match current answers located in #thegrid with possible #anskey array, iterate for each item
#anskey={
:wm01=>"c3",:wm02=>"c2",:wm03=>"c1",:wm04=>"b3",:wm05=>"b1",:wm06=>"a3",:wm07=>"a2",:wm08=>"a1",
:wm09=>"a3",:wm10=>"c1",:wm11=>"a1",:wm12=>"c3",:wm13=>"c3",:wm14=>"c1",:wm15=>"c3",:wm16=>"a1",
:wm17=>"b1",:wm18=>"b2",:wm19=>"b3",:wm20=>"a2",:wm21=>"b2",:wm22=>"b2",:wm23=>"c2",:wm24=>"b2",
:wm25=>"a1",:wm26=>"a1",:wm27=>"a3",:wm28=>"a3",:wm29=>"c1",:wm30=>"c1",:wm31=>"c3",:wm32=>"c3",
:wm33=>"a1",:wm34=>"a1",:wm35=>"c1",:wm36=>"c1",:wm37=>"a3",:wm38=>"a3",:wm39=>"c3",:wm40=>"c3"
}
#
# scan board for available move locations
#keys_with_o = board.grid.select{ |k, v| v == "O" }.keys # find Os on the board
#keys_with_x = board.grid.select{ |k, v| v == "X" }.keys # find Xs on the board
#answers_array = [] # initialize answers array
if board.grid[:b2] == " " #AND center spot is empty
ai_spot = "b2"
# puts "ai takes center "+ai_spot
#move = ai_spot.to_sym #must return this answer as a symbol
else
# TODO - Ai attempts win
i = 0
until i == 4
attempt_win(board) #run 3x then run attempt_block
i = i+1 # add 1 to i
if i == 4
puts "running attempt_block..."
attempt_block(board)
end
end
end
return #move # had this guy in the wrong place
end
def attempt_win(board)
#ai_winmoves.each do |k, v| # go through each win move in the ai_winmoves array above.
ai_keys = v.select{ |k, v| v == "O"}.keys # grab all computer player's Os from the value hash
intersection = ai_keys & #keys_with_o # get common elements between two arrays..note: keys_with_o = all current O's on game board
if intersection.length >=2 # when two intersections exist it means two O's are on the board
#answers_array << k # add to answers array per iteration
#answers_array.each do |key|
# answer = #anskey[#thing.last].to_sym
puts "which moves can ai win with?"
puts #anskey[key]
answer = #anskey[key].to_sym
puts "attempt win"
puts answer
if board.grid[answer] == " " #if win move space is empty take it
#move = answer
else #check for a block move
# attempt_block # handled at line 162
end
end
end
end # END #ai_winmoves.each do |k,v|
end
def attempt_block(board)
puts "attempt block method - hi"
# thing = [] # initialize thing array
#human_winmoves.each do |k,v| # for test - go threw each win moves.
# get common elements between two arrays..recall from above that v contains a hash
human_keys = v.select{ |k, v| v == "X"}.keys
# which moves can I take to block human
intersection = human_keys & #keys_with_x
if intersection.length >= 2
puts "intersection"
puts intersection
#answers_array << k # adds a key per iteration
puts "#answers_array << k"
puts #anskey[k]
#answers_array.each do |key|
puts "which moves can ai block with?"
puts #anskey[key]
answer = #anskey[key].to_sym
puts "attempt block"
puts answer
# if board.spot_taken?(answer)
if board.grid[answer] != " " # spot taken
puts "space taken can not block 2: " + answer.to_s
else
puts answer.to_s+" blocked"
#move = answer # for test - at last intersection value found...return it as move value
return #move
end
end
end
end # END #human_winmoves.each do |k,v|
end
end
If you wanna see the entire player_spec.rb file...
require 'game'
require 'board'
describe 'Player class' do
before (:each) do
#Dry it up
#player_human = Player.new('X')
#player_computer = Player.new('O')
#board = Board.new
#game = Game.new(#player_human, #player_computer, #board)
end
describe 'move_human' do
before (:each) do
# first set up my expectations
#player_human.should_receive(:puts).with("human move...")
#player_human.stub(:gets).and_return("a1")
end
it 'receives cli input and prints text to screen' do
# now trigger them
#player_human.move_human("X", #board)
end
it 'returns a move value' do
# now trigger them
#player_human.move_human("X", #board).should eq(:a1) #return the value is what I mocked?
end
end
describe 'move_computer' do
it 'should print - ...computer move... - to screen' do
# first set up my expectations
#player_computer.should_receive(:puts).with("computer move...")
# now trigger them
#player_computer.move_computer("O", #board)
end
it 'returns expected first move b2' do
#player_computer.move_computer("O", #board).should eq(:b2)
end
end
describe 'attempt_win' do
before (:each) do
#board.grid[:b2] == "X"
end
xit 'computer looks for any possible win move'
it 'computer returns a value' do
#player_computer.attempt_win(#board).should_not be(nil)
end
end
describe 'attempt_block'do
xit 'looks for a block move'
end
end
The error tells you pretty clearly what is wrong, if you know how to read it right:
1) Player class attempt_win computer returns a value
Failure/Error: #player_computer.attempt_win(#board).should_not be(nil)
NoMethodError:
undefined method `each' for nil:NilClass
# ./lib/player.rb:171:in `attempt_win'
# ./spec/player_spec.rb:47:in `block (3 levels) in <top (required)>'
This is telling you several things:
The line of your spec where the error occurred is #player_computer.attempt_win(#board).should_not be(nil).
The error is due to each being called on an object that does not respond to that message.
The object it was called on is nil.
The error occurred at ./lib/player.rb:171 in the attempt_win method, or in some internal library method called by attempt_win. (You can run your spec with the --backtrace flag to get the full backtrace. By default, RSpec tries to filter it to only the relevant lines to reduce noise.)
Looking at your code, the error suggests that #ai_winmoves has not been initialized and had the value of nil when attempt_win was called.

Faster textual data processing in BASH

I've got a speed question. I have a bash script which parses information from TheTvDb.com. It downloads nearly 40,000 lines of data, then reduces it down to about 5000 lines of data which gets written to the hard disk. Then it reads the file and parses it into several files which are used later as a lookup table. It's basically taking all the information it sees before each "/Episode" and writing it to a specific file, then resetting for the next one.
It has to synchronize on the "/Episode" tag because there is a "FirstAired" tag outside of the episode tags. This ensures that the data is drawn in sequence rather then depending on each individual tag to be relating to a episode.
here is the code in question.
if [ -f "$mythicalLibrarian/$NewShowName/$NewShowName.xml" ]; then
Ename=""
actualEname=""
FAired=""
SeasonNr=""
EpisodeNr=""
recordNumber=0
echo "Parsing Downloaded information: $NewShowName.xml "
while read line
do
if [[ $line == \<\/Episode\> ]]; then
(( ++recordNumber ))
echo -ne "Building Record:$recordNumber ${actualEname:0:20} \r" 1>&2
echo "$actualEname" >> "$mythicalLibrarian/$NewShowName/$NewShowName.actualEname.txt"&
Ename=`echo "$actualEname" |sed 's/;.*//'`
echo "$Ename" >> "$mythicalLibrarian/$NewShowName/$NewShowName.Ename.txt"&
echo "$FAired" >> "$mythicalLibrarian/$NewShowName/$NewShowName.FAired.txt"&
echo "$SeasonNr" >> "$mythicalLibrarian/$NewShowName/$NewShowName.S.txt"&
echo "$EpisodeNr" >> "$mythicalLibrarian/$NewShowName/$NewShowName.E.txt"&
Ename=""
actualEname=""
FAired=""
SeasonNr=""
EpisodeNr=""
#Get actual show name
elif [[ $line == \<EpisodeName\>* ]]; then
actualEname=`echo "$line" | sed -e s/'<\/EpisodeName>'// -e s/'<EpisodeName>'// -e s/'\&amp\;'/'\&'/ -e s/'\&quot\;'/'\"'/ -e s/'\&amp\;'/'\&'/ -e s/'\&ndash\;'/'-'/ -e s/'\&lt\;'/'\<'/ -e 's/'\&gt\;'/'\>'/' |tr -d '|\?\*\<\"\:\>\+\\\[\]\/'`
#Get OriginalAirDate
elif [[ $line == \<FirstAired\>* ]]; then
FAired=`echo "$line" | sed -e s/'<FirstAired>'//g -e s/'<\/FirstAired>'//g`
#Get Season number
elif [[ $line == \<SeasonNumber\>* ]]; then
SeasonNr=`echo "$line" |sed -e s/'<SeasonNumber>'// -e s/'<\/SeasonNumber>'//`
#Get Episode number
elif [[ $line == \<EpisodeNumber\>* ]]; then
EpisodeNr=`echo "$line" |sed -e 's/<EpisodeNumber>//' -e 's/<\/EpisodeNumber>//'`
fi
done < "$mythicalLibrarian/$NewShowName/$NewShowName.xml"
chmod 777 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".actualEname.txt
chmod 666 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".Ename.txt
chmod 666 "$mythicalLibrarian/$NewShowName/$NewShowName".FAired.txt
chmod 666 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".S.txt
chmod 666 "$mythicalLibrarian/$NewShowName/$NewShowName".E.txt
GotNewInformation=1
elif [ ! -f "$mythicalLibrarian/$NewShowName/$NewShowName.xml" ]; then
echo "COULD NOT DOWNLOAD:www.thetvdb.com/api/$APIkey/series/$SeriesID/all/$Language.xml">>"$mythicalLibrarian"/output.log
fi
Here is some of the data it is processing
<?xml version="1.0" encoding="UTF-8" ?>
<Data><Series>
<Actors>|Fred Rogers|Adair Roth|Bert Lloyd|Bud Alder|Carol Saunders|Carole Switala|Deborah Neal Stampo|Don Brockett|Elsie Neal|Emilie Jacobson|Fred Michael|John Reardon|Jos|Judy Rubin|Keith David|Lenny Meledandri|Michael Horton|Robert Trow|Yoshi Ito|</Actors>
<Airs_DayOfWeek></Airs_DayOfWeek>
<Airs_Time></Airs_Time>
<ContentRating></ContentRating>
<FirstAired>1968-02-01</FirstAired>
<Genre>|Children|</Genre>
<Network>PBS</Network>
<NetworkID></NetworkID>
<Overview>"In a little toy neighborhood, a tiny trolley rolls past a house at the end of a street.
<Runtime>30</Runtime>
<SeriesID>6843</SeriesID>
<SeriesName>Mister Rogers' Neighborhood</SeriesName>
<Status>Ended</Status>
<added></added>
<addedBy></addedBy>
<banner>graphical/77750-g.jpg</banner>
<fanart>fanart/original/77750-1.jpg</fanart>
<poster></poster>
<zap2it_id>SH002930</zap2it_id>
</Series>
<Episode>
<EpisodeName>Change (1)</EpisodeName>
<EpisodeNumber>1</EpisodeNumber>
<FirstAired>1968-02-19</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Change (2)</EpisodeName>
<EpisodeNumber>2</EpisodeNumber>
<FirstAired>1968-02-20</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Change (3)</EpisodeName>
<EpisodeNumber>3</EpisodeNumber>
<FirstAired>1968-02-21</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Change (4)</EpisodeName>
<EpisodeNumber>4</EpisodeNumber>
<FirstAired>1968-02-22</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Change (5)</EpisodeName>
<EpisodeNumber>5</EpisodeNumber>
<FirstAired>1968-02-23</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 6</EpisodeName>
<EpisodeNumber>6</EpisodeNumber>
<FirstAired>1968-02-26</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 7</EpisodeName>
<EpisodeNumber>7</EpisodeNumber>
<FirstAired>1968-02-27</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 8</EpisodeName>
<EpisodeNumber>8</EpisodeNumber>
<FirstAired>1968-02-28</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 9</EpisodeName>
<EpisodeNumber>9</EpisodeNumber>
<FirstAired>1968-02-29</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 10</EpisodeName>
<EpisodeNumber>10</EpisodeNumber>
<FirstAired>1968-03-01</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 11</EpisodeName>
<EpisodeNumber>11</EpisodeNumber>
<FirstAired>1968-03-04</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 12</EpisodeName>
<EpisodeNumber>12</EpisodeNumber>
<FirstAired>1968-03-05</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 13</EpisodeName>
<EpisodeNumber>13</EpisodeNumber>
<FirstAired>1968-03-06</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 14</EpisodeName>
<EpisodeNumber>14</EpisodeNumber>
<FirstAired>1968-03-07</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 15</EpisodeName>
<EpisodeNumber>15</EpisodeNumber>
<FirstAired>1968-03-08</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Welcome Donkey Hodie (1)</EpisodeName>
<EpisodeNumber>16</EpisodeNumber>
<FirstAired>1968-03-11</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Welcome Donkey Hodie (2)</EpisodeName>
<EpisodeNumber>17</EpisodeNumber>
<FirstAired>1968-03-12</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Welcome Donkey Hodie (3)</EpisodeName>
<EpisodeNumber>18</EpisodeNumber>
<FirstAired>1968-03-13</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Welcome Donkey Hodie (4)</EpisodeName>
<EpisodeNumber>19</EpisodeNumber>
<FirstAired>1968-03-14</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Welcome Donkey Hodie (5)</EpisodeName>
<EpisodeNumber>20</EpisodeNumber>
<FirstAired>1968-03-15</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 21</EpisodeName>
<EpisodeNumber>21</EpisodeNumber>
<FirstAired>1968-03-18</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 22</EpisodeName>
<EpisodeNumber>22</EpisodeNumber>
<FirstAired>1968-03-19</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 23</EpisodeName>
<EpisodeNumber>23</EpisodeNumber>
<FirstAired>1968-03-20</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 24</EpisodeName>
<EpisodeNumber>24</EpisodeNumber>
<FirstAired>1968-03-21</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 25</EpisodeName>
<EpisodeNumber>25</EpisodeNumber>
<FirstAired>1968-03-22</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 26</EpisodeName>
<EpisodeNumber>26</EpisodeNumber>
<FirstAired>1968-03-25</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 27</EpisodeName>
<EpisodeNumber>27</EpisodeNumber>
<FirstAired>1968-03-26</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 28</EpisodeName>
<EpisodeNumber>28</EpisodeNumber>
<FirstAired>1968-03-27</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 29</EpisodeName>
<EpisodeNumber>29</EpisodeNumber>
<FirstAired>1968-03-28</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 30</EpisodeName>
<EpisodeNumber>30</EpisodeNumber>
<FirstAired>1968-03-29</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Red Monster (1)</EpisodeName>
<EpisodeNumber>31</EpisodeNumber>
<FirstAired>1968-04-01</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Red Monster (2)</EpisodeName>
<EpisodeNumber>32</EpisodeNumber>
<FirstAired>1968-04-02</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Red Monster (3)</EpisodeName>
<EpisodeNumber>33</EpisodeNumber>
<FirstAired>1968-04-03</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Red Monster (4)</EpisodeName>
<EpisodeNumber>34</EpisodeNumber>
<FirstAired>1968-04-04</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Red Monster (5)</EpisodeName>
<EpisodeNumber>35</EpisodeNumber>
<FirstAired>1968-04-05</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 36</EpisodeName>
<EpisodeNumber>36</EpisodeNumber>
<FirstAired>1968-04-08</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 37</EpisodeName>
<EpisodeNumber>37</EpisodeNumber>
<FirstAired>1968-04-09</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 38</EpisodeName>
<EpisodeNumber>38</EpisodeNumber>
<FirstAired>1968-04-10</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 39</EpisodeName>
<EpisodeNumber>39</EpisodeNumber>
<FirstAired>1968-04-11</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 40</EpisodeName>
<EpisodeNumber>40</EpisodeNumber>
<FirstAired>1968-04-12</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 41</EpisodeName>
<EpisodeNumber>41</EpisodeNumber>
<FirstAired>1968-04-15</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 42</EpisodeName>
<EpisodeNumber>42</EpisodeNumber>
<FirstAired>1968-04-16</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 43</EpisodeName>
<EpisodeNumber>43</EpisodeNumber>
<FirstAired>1968-04-17</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 44</EpisodeName>
<EpisodeNumber>44</EpisodeNumber>
<FirstAired>1968-04-18</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 45</EpisodeName>
<EpisodeNumber>45</EpisodeNumber>
<FirstAired>1968-04-19</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 46</EpisodeName>
<EpisodeNumber>46</EpisodeNumber>
<FirstAired>1968-04-22</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 47</EpisodeName>
<EpisodeNumber>47</EpisodeNumber>
<FirstAired>1968-04-23</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 48</EpisodeName>
<EpisodeNumber>48</EpisodeNumber>
<FirstAired>1968-04-24</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 49</EpisodeName>
<EpisodeNumber>49</EpisodeNumber>
<FirstAired>1968-04-25</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 50</EpisodeName>
<EpisodeNumber>50</EpisodeNumber>
<FirstAired>1968-04-26</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 51</EpisodeName>
<EpisodeNumber>51</EpisodeNumber>
<FirstAired>1968-04-29</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 52</EpisodeName>
<EpisodeNumber>52</EpisodeNumber>
<FirstAired>1968-04-30</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 53</EpisodeName>
<EpisodeNumber>53</EpisodeNumber>
<FirstAired>1968-05-01</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 54</EpisodeName>
<EpisodeNumber>54</EpisodeNumber>
<FirstAired>1968-05-02</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 55</EpisodeName>
<EpisodeNumber>55</EpisodeNumber>
<FirstAired>1968-05-03</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 56</EpisodeName>
<EpisodeNumber>56</EpisodeNumber>
<FirstAired>1968-05-06</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 57</EpisodeName>
<EpisodeNumber>57</EpisodeNumber>
<FirstAired>1968-05-07</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 58</EpisodeName>
<EpisodeNumber>58</EpisodeNumber>
<FirstAired>1968-05-08</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 59</EpisodeName>
<EpisodeNumber>59</EpisodeNumber>
<FirstAired>1968-05-09</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 60</EpisodeName>
<EpisodeNumber>60</EpisodeNumber>
<FirstAired>1968-05-10</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 61</EpisodeName>
<EpisodeNumber>61</EpisodeNumber>
<FirstAired>1968-05-13</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 62</EpisodeName>
<EpisodeNumber>62</EpisodeNumber>
<FirstAired>1968-05-14</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 63</EpisodeName>
<EpisodeNumber>63</EpisodeNumber>
<FirstAired>1968-05-15</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 64</EpisodeName>
<EpisodeNumber>64</EpisodeNumber>
<FirstAired>1968-05-16</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 65</EpisodeName>
<EpisodeNumber>65</EpisodeNumber>
<FirstAired>1968-05-17</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 66</EpisodeName>
<EpisodeNumber>66</EpisodeNumber>
<FirstAired>1968-05-20</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 67</EpisodeName>
<EpisodeNumber>67</EpisodeNumber>
<FirstAired>1968-05-21</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 68</EpisodeName>
<EpisodeNumber>68</EpisodeNumber>
<FirstAired>1968-05-22</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 69</EpisodeName>
<EpisodeNumber>69</EpisodeNumber>
<FirstAired>1968-05-23</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 70</EpisodeName>
<EpisodeNumber>70</EpisodeNumber>
<FirstAired>1968-05-24</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 71</EpisodeName>
<EpisodeNumber>71</EpisodeNumber>
<FirstAired>1968-05-27</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
<Episode>
<EpisodeName>Show 72</EpisodeName>
<EpisodeNumber>72</EpisodeNumber>
<FirstAired>1968-05-28</FirstAired>
<SeasonNumber>1</SeasonNumber>
</Episode>
The problem is that on a i7 processor this takes 14.5 seconds. It is about 10x slower on my media center. I tried using a case statement which takes 15 seconds on the fast processor.
I would like to know about how to speed this process up. It seems that this is ridiculously slow for BASH which is supposed to be designed around data manipulation and file operations.
You will get a considerable speedup by dropping the & from the end of all those echo statements.
Test1:
$ time { for i in {1..1000}; do echo "hello"& done >/dev/null; } | cat
real 0m10.357s
user 0m2.764s
sys 0m15.441s
The cat eats the "done" messages when this is done at the command line. A colon could be used instead of cat to suppress the "done" messages from the first timed test. It's not the program that's doing it, it's the fact that the backgrounded processes are part of a pipe.
Test2:
$ time { for i in {1..1000}; do echo "hello"; done >/dev/null; }
real 0m0.152s
user 0m0.132s
sys 0m0.020s
Note that this was on a very slow, old machine.
You may also get a speed improvement by using Bash's regex and string processing features instead of repeatedly spawning multiple external utilities in a loop.
Example:
elif [[ $line == \<EpisodeName\>* ]]; then
actualEname=${line//<\/EpisodeName>/}
actualEname=${actualEname//<EpisodeName>/}
actualEname=${actualEname//&/&}
actualEname=${actualEname//–/-}
for string in '|' '<' '>' '"' '?' '*' '<' '>' ':' '"' '+' '\' '[' ']' '/'
do
actualEname=${actualEname//$string}
done
You had an extra & in that line and a lot of unnecessary single quotes and escaping, by the way. Also, you're converting HTML entities and then deleting them. Why not just delete them to begin with? You also seem to be missing some g (global) modifiers.
Test3:
$ time { for i in {1..100}; do
line='<EpisodeName><foo&bar–baz>Season–3–"quux"?*<>:"+\[]/</EpisodeName>'
actualEname=$(echo "$line" | sed -e 's/<\/EpisodeName>//' -e 's/<EpisodeName>//' -e 's/&/\&/g' -e 's/"/"/g' -e 's/–/-/g' -e 's/</</g' -e 's/>/>/g' |tr -d '|?*<":>+\\[]/')
done; }
real 0m7.779s
user 0m3.164s
sys 0m5.436s
Test4:
$ time { for i in {1..100}; do
line='<EpisodeName><foo&bar–baz>Season–3–"quux"?*<>:"+\[]/</EpisodeName>
actualEname=${line//<\/EpisodeName>/}
actualEname=${actualEname//<EpisodeName>/}
actualEname=${actualEname//&/&}
actualEname=${actualEname//–/-}
for string in '|' '<' '>' '"' '\?' '\*' '<' '>' ':' '"' '+' '\\' '[' ']' '\/'
do
actualEname=${actualEname//$string}
done
done; }
real 0m5.403s
user 0m2.492s
sys 0m2.960s
Use something like XMLStarlet which is designed to process XML.
The slowdown is most likely due to the very high number of process spawns that are happening in that script (sed, tr).
You could achieve a much faster result by calling a program with an XML parser to read it in, and output to the various files. If you need to keep it in bash, maybe find something that can do XSLT to transform from the XML to the format used in the files and divide it up.
Personally I would do that sort of thing in Perl.
BASH which is supposed to be designed around data manipulation and file operations.
Bash is designed for interactive command processing and linking programs together via pipes. Heavy data processing is not the design space of any *sh that I know of.
Python or Perl would be a much better choice for the problem space.
I just tried this:
echo "Parsing Downloaded information: $NewShowName.xml "
while read line
do
if [[ $line == \<\/Episode\> ]]; then
(( ++recordNumber ))
echo -ne "Building Record:$recordNumber ${actualEname:0:20} \r" 1>&2
echo "$EpisodeName" >> "$mythicalLibrarian/$NewShowName/$NewShowName.actualEname.txt"&
Ename=`echo "$actualEname" |sed 's/;.*//'`
echo "$EpisodeName" >> "$mythicalLibrarian/$NewShowName/$NewShowName.Ename.txt"&
echo "$FirstAired" >> "$mythicalLibrarian/$NewShowName/$NewShowName.FAired.txt"&
echo "$SeasonNumber" >> "$mythicalLibrarian/$NewShowName/$NewShowName.S.txt"&
echo "$EpisodeNumber" >> "$mythicalLibrarian/$NewShowName/$NewShowName.E.txt"&
EpisodeName=""
actualEname=""
FirstAired=""
SeasonNumber=""
EpisodeNumber=""
else
var=`echo $line |tr '<>' ' '|awk '{print $1}'`
value=`echo "$line"|sed -e s/'<'"$var"'>'// -e s/'<\/'"$var"'>'// -e s/'\&amp\;'/'\&'/ -e s/'\&quot\;'/'\"'/ -e s/'\&amp\;'/'\&'/ -e s/'\&ndash\;'/'-'/ -e s/'\&lt\;'/'\<'/ -e 's/'\&gt\;'/'\>'/' |tr -d '|\?\*\<\"\:\>\+\\\[\]\/'`
eval $var="'$value'"
fi
Which took 43 seconds on the faster processor
Holy cow Dennis Williamson, It parses in less then 1/2 second. It just flickers across the screen. It used to take 15 seconds, but now it's so quick that I can't even tell that it's happening.
These are the changes that Dennis Williamson suggested. I'm just posting it here.
echo "Parsing Downloaded information: $NewShowName.xml "
while read line
do
if [[ $line == \<\/Episode\> ]]; then
(( ++recordNumber ))
echo -ne "Building Record:$recordNumber ${actualEname:0:20} \r" 1>&2
echo "$actualEname" >> "$mythicalLibrarian/$NewShowName/$NewShowName.actualEname.txt"
echo "$Ename" >> "$mythicalLibrarian/$NewShowName/$NewShowName.Ename.txt"
echo "$FAired" >> "$mythicalLibrarian/$NewShowName/$NewShowName.FAired.txt"
echo "$SeasonNr" >> "$mythicalLibrarian/$NewShowName/$NewShowName.S.txt"
echo "$EpisodeNr" >> "$mythicalLibrarian/$NewShowName/$NewShowName.E.txt"
Ename=""
actualEname=""
FAired=""
SeasonNr=""
EpisodeNr=""
#Get actual show name
elif [[ $line == \<EpisodeName\>* ]]; then
line=${line/<\/EpisodeName>/}
line=${line/<EpisodeName>/}
line=${line/<}
line=${line/>/}
line=${line/"/}
line=${line/&/&}
line=${line/\|/}
line=${line/\?/}
line=${line/\*/}
line=${line/\:/}
line=${line/\+/}
line=${line/\\/}
line=${line/\//}
line=${line/\[/}
line=${line/\]/}
line=${line/\'/}
line=${line/\"/}
actualEname=${line/–/-}
Ename=${actualEname/;*/}
#Get OriginalAirDate
elif [[ $line == \<FirstAired\>* ]]; then
line=${line/<\/FirstAired>/}
line=${line/<FirstAired>/}
FAired=$line
#Get Season number
elif [[ $line == \<SeasonNumber\>* ]]; then
line=${line/<\/SeasonNumber>/}
line=${line/<SeasonNumber>/}
SeasonNr=$line
#Get Episode number
elif [[ $line == \<EpisodeNumber\>* ]]; then
line=${line/<\/EpisodeNumber>/}
line=${line/<EpisodeNumber>/}
EpisodeNr=$line
fi
done < "$mythicalLibrarian/$NewShowName/$NewShowName.xml"
chmod 666 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".actualEname.txt
chmod 666 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".Ename.txt
chmod 666 "$mythicalLibrarian/$NewShowName/$NewShowName".FAired.txt
chmod 666 "$mythicalLibrarian"/"$NewShowName"/"$NewShowName".S.txt
chmod 666 "$mythicalLibrarian/$NewShowName/$NewShowName".E.txt
GotNewInformation=1

Cooler ASCII Spinners? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
In a console app, an ascii spinner can be used, like the GUI wait cursor, to indicate that work is being done. A common spinner cycles through these 4 characters: '|', '/', '-', '\'
What are some other cyclical animation sequences to spice up a console application?
Lots of choices with Unicode, including ⌚ and ⌛!
← ↖ ↑ ↗ → ↘ ↓ ↙
▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▇ ▆ ▅ ▄ ▃ ▁
▉▊▋▌▍▎▏▎▍▌▋▊▉
▖ ▘ ▝ ▗
┤ ┘ ┴ └ ├ ┌ ┬ ┐
◢ ◣ ◤ ◥
◰ ◳ ◲ ◱
◴ ◷ ◶ ◵
◐ ◓ ◑ ◒
◡◡ ⊙⊙ ◠◠
⣾⣽⣻⢿⡿⣟⣯⣷ ⠁⠂⠄⡀⢀⠠⠐⠈ The entire braille block, even in random order http://www.fileformat.info/info/unicode/block/braille_patterns/images.htm
Watch them in action here:
var nl = "\r\n";
var spinners = [
"←↖↑↗→↘↓↙",
"▁▃▄▅▆▇█▇▆▅▄▃",
"▉▊▋▌▍▎▏▎▍▌▋▊▉",
"▖▘▝▗",
"▌▀▐▄",
"┤┘┴└├┌┬┐",
"◢◣◤◥",
"◰◳◲◱",
"◴◷◶◵",
"◐◓◑◒",
"|/-\\",
".oO#*", ["◡◡", "⊙⊙", "◠◠"],
["◜ ", " ◝", " ◞", "◟ "],
"◇◈◆",
"⣾⣽⣻⢿⡿⣟⣯⣷",
"⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿",
"⠁⠂⠄⡀⢀⠠⠐⠈", [">))'>", " >))'>", " >))'>", " >))'>", " >))'>", " <'((<", " <'((<", " <'((<"],
[" /\\O\n /\\/\n /\\\n / \\\n LOL LOL", " _O\n //|_\n |\n /|\n LLOL", " O\n /_\n |\\\n / |\n LOLLOL"],
[
"╔════╤╤╤╤════╗\n║ │││ \\ ║\n║ │││ O ║\n║ OOO ║",
"╔════╤╤╤╤════╗\n║ ││││ ║\n║ ││││ ║\n║ OOOO ║",
"╔════╤╤╤╤════╗\n║ / │││ ║\n║ O │││ ║\n║ OOO ║",
"╔════╤╤╤╤════╗\n║ ││││ ║\n║ ││││ ║\n║ OOOO ║"
],
[
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\===%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\===%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\===%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\===%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\===%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ==%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ =%^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ %^,"+nl+
" ' \\# >"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%"+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%=="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%==="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"'-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%==="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ' ______>,^____\\"+nl+
" ' \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%==="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' \\ ,^%==="+nl+
" ' \\# <"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '|"+nl+
" ' | ,^%---"+nl+
" ' |# < \\"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '/"+nl+
" ' / ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '|"+nl+
" ' | ,^%---"+nl+
" ' |# < \\"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '/"+nl+
" ' / ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '/"+nl+
" ' / ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" ______>,^____\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '|"+nl+
" ' / ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" _______>,^___\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' | ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '|"+nl+
" ' / ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" _______>,^___\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" '\\"+nl+
" ' | ,^%---"+nl+
" ' /# < \\"+nl+
" ' `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
"' '/"+nl+
" ' ' / \\_,^%---"+nl+
" ' ' /# < \\"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
";''"+nl+
" ' '/ /"+nl+
" ' ' / \\,^%==="+nl+
" ' ' /# <"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" ;''"+nl+
" ' '/ /"+nl+
" ' ' / \\,^%==="+nl+
" ' ' /# <"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" ;''"+nl+
" '"+nl+
" ' '/ /"+nl+
" ' ' / \\,^%==="+nl+
" /# <"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" ;'"+nl+
" '"+nl+
" ' '/ /"+nl+
" ' ' / \\,^%=="+nl+
" /# <"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" ; "+nl+
" '"+nl+
" ' '/ /"+nl+
" ' ' / \\,^%="+nl+
" /# <"+nl+
" `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
"'. ;'."+nl+
" '- .' '/ _"+nl+
"*) / ' ' / \\=%"+nl+
" _\\ ' ' /# >"+nl+
"'~ `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
"`-."+nl+
" '. ;"+nl+
" '- . ' '/_"+nl+
"{ (*) / ' ' / \\==#^"+nl+
" _\\ ' ' /# >"+nl+
".;;'~ `\\/> _"+nl+
" ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" \\\\\\\\"+nl+
".-' `-. ;"+nl+
" '.'"+nl+
" '- '|"+nl+
" {{ (*) / '' |===#^"+nl+
" _\\ |# >"+nl+
" .;;'~ `\\/> _"+nl+
"/~~''~ ________>,^__\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" \\\\\\\\ ;"+nl+
" .-' `-. '"+nl+
" .-' '. ''"+nl+
" .' '- \\"+nl+
"' {{ (*) /===#^,/"+nl+
"-. _\\ >"+nl+
" ~-. .;;'~|# \\/> _"+nl+
" ///~~''~______`__>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" \\\\\\\\ "+nl+
" .-' `-."+nl+
" .-' '."+nl+
" .' '- \\"+nl+
"(`-.-' {{ (*) / ===#^,/"+nl+
" } .'~-. _\\/ >"+nl+
" (/ ~-. .;;'~ / \\/> "+nl+
" ///~''~_____/#____>,^"+nl+
" \\-=-=-`-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" \\\\\\\\ YIKES"+nl+
" .-' `-."+nl+
" .-' '. /"+nl+
" .' '- ---#^,/"+nl+
" (`-.-' {{ (*) / / >"+nl+
" } .'~-. _\\ \\/> "+nl+
" (/ ~-. .;;'~_____>,^"+nl+
" ///~''~-=-=|#-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" YIKES"+nl+
" \\\\\\\\"+nl+
" .-' `-. \\"+nl+
" .-' '. ---#^,/"+nl+
" .' '- / >"+nl+
" (`-.-' {{ (*) / \\/> "+nl+
" } .'~-. _\\___>,^"+nl+
" (/ ~-. .;;'~/=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~/#-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" YIKES"+nl+
" "+nl+
" \\\\\\\\ _"+nl+
" .-' `-. ---#^,/"+nl+
" .-' '. / >"+nl+
" .' '- \\/> "+nl+
" (`-.-' . . ` {{ (*) /___>,^"+nl+
" } .'~-. . ` _\\-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-/-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" YIKES"+nl+
" "+nl+
" _"+nl+
" ` . \\\\\\\\ ---#^,/"+nl+
" ` ` .-' `-. . '/ >"+nl+
" ` .-' '. ' \\/> "+nl+
" `' ` '-___>,^"+nl+
" (`-.-' . . ` {{ (*) /-=-=-/{}"+nl+
"-~-~-~-~-~-~-`-. . ` ' \\~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" YIKES"+nl+
" "+nl+
" _"+nl+
" ` . ' ---=^,/"+nl+
" ` ` . . / >"+nl+
" ` ` \\\\\\\\ ' \\/> "+nl+
" ` ` .-' `-. ______>,^"+nl+
" ` .-' '.-=-=-=-/{}"+nl+
"~-~-~-~-~-.-~-~-~-'-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" YIKES"+nl+
" "+nl+
"` . ' _"+nl+
" ` ` ---#^,/"+nl+
" ` ` ' / >"+nl+
" ` ` \\/> "+nl+
" ` ` __________>,^"+nl+
" ` \\\\\\\\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~' `-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" ."+nl+
" ' _"+nl+
" ` . ---#^,/"+nl+
" ` ` / >"+nl+
" ` ` . \\/> "+nl+
" ` ` . __________>,^"+nl+
" ` ` ` \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~\\\\\\\\.~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ` . _"+nl+
" `` ' ===-^,/"+nl+
" ` ` >"+nl+
" ` ' \\/> "+nl+
" ` . __________>,^"+nl+
" ` \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-`-.-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" . ` ' _"+nl+
" ` ` ===-^,/"+nl+
" . >"+nl+
" ` ' \\/> "+nl+
" . __________>,^"+nl+
" ` \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ` _"+nl+
" ` ===-^,/"+nl+
" ` ` ' >"+nl+
" ` \\/> "+nl+
" __________>,^"+nl+
" \\-=-=-=-=-=-/{я}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ` ' _"+nl+
" ` ===-^,/"+nl+
" >"+nl+
" \\/> "+nl+
" __________>,^"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" _"+nl+
" ===%^,/"+nl+
" >"+nl+
" \\/> "+nl+
" __________>,^"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" \\"+nl+
" ---%^,/"+nl+
" / >"+nl+
" _/> "+nl+
" __________>,^"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" _"+nl+
" ---%^,/ "+nl+
" / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" /> _"+nl+
" _______/_>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===-^,"+nl+
" >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" \\/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===-^,"+nl+
" >"+nl+
" \\/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" \\/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" Rats. / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" Rats. / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" Rats. / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" я \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" Rats. / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" Rats. / >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===-^,"+nl+
" >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ===%^,"+nl+
" >"+nl+
" _/> _"+nl+
" _________>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-я~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" / >"+nl+
" /> _"+nl+
" _______/_>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"+nl+
"-ejm97-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~",
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" "+nl+
" ---%^,"+nl+
" I lost my fishing rod. / >"+nl+
" /> _"+nl+
" _______/_>,^_\\"+nl+
" \\-=-=-=-=-=-/{}"+nl+
"-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~"+nl+
"~ejm97~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-"], // "Fishing" taken from http://asciimator.net/kangaroo/fishing.html
];
for (var s = 0; s < spinners.length; ++s) {
var spinner = spinners[s];
var div = document.createElement('div');
var el = document.createElement('pre');
div.appendChild(el);
document.body.appendChild(div);
(function(spinner, el) {
var i = 0;
setInterval(function() {
el.innerHTML = spinner[i];
i = (i + 1) % spinner.length;
}, 300);
})(spinner, el);
}
pre {
font-family: monospace;
font-size: 1.5em;
font-weight: bold;
border: 1px solid #eee;
display: inline-block;
margin: .25em;
}
There's more # cli-spinners, courtesy of Sindre Sorhus.
You can nab the JSON for them here.
I JavaScriptified them here: JsBin
Balloons...
. o O # *
If you have more than one character worth of space, you can use animated ASCII art. For example, you can do a progress bar like:
[ ]
[== ]
[===== ]
[======== ]
or a "bouncing ball" progress indicator (that moves back and forth) like:
(-*--------) // moving -->
(-----*----) // moving -->
(---------*) // moving -->
(--------*-) // moving <--
(---*------) // moving <--
(*---------) // moving <--
Something more advanced like this loading animation might also work.
Edit:
There's also the "executive desk toy"
╔════╤╤╤╤════╗ ╔════╤╤╤╤════╗ ╔════╤╤╤╤════╗ ╔════╤╤╤╤════╗
║ │││ \ ║ ║ ││││ ║ ║ / │││ ║ ║ ││││ ║
║ │││ O ║ -> ║ ││││ ║ -> ║ O │││ ║ -> ║ ││││ ║
║ OOO ║ ║ OOOO ║ ║ OOO ║ ║ OOOO ║
And of course there's the ultimate example of animated ASCII art, if you had the time to implement something similar (it would take "spicing up a console application" to the extreme).
Edit: If your console supports color, you can also spice up an otherwise-boring standard spinner by cycling through colors as you spin. Start off with a red line, then slowly fade through the rainbow up to violet as you spin. This can look especially cool with the "bouncing ball" indicator above if you have the ball "paint" the bar a different color on every pass.
Definitely LOLLERSKATES!
/\O | _O | O
/\/ | //|_ | /_
/\ | | | |\
/ \ | /| | / |
LOL LOL | LLOL | LOLLOL
-----------+----------+-----------
Frame 0 | Frame 1 | Frame 2
There used to be a a DOS linker named blinker, by Blink Inc. It would display an animation similar to this while it was working:
(o)(o)
(-)(-)
(_)(_)
With the first frame displaying for about a second, and the other two animating briefly once a second or two, making the command line appear to blink its eyes. The effect was pretty cool, actually.
The linker even had options to blink one eye, and you could choose which eye would blink.
I've used a cycle of
Working.
Working..
Working...
Inspirational I know
If you know how far through the process you are I like the percentage bar. It looks nice, feels intuitive and is easy to implement:
| 0%
|| 5%
|||||| 25%
||||||||||||||||||||| 100%
fish is a Python module that animates an ASCII fish going back and forth, and who doesn't like the rare console fish?
>))'>
>))'>
>))'>
<'((<
<'((<
Try these
'+', 'x'
'v', '<', '^', '>'
All taken from:
http://llizard.cwahi.net/animals.html
Bats Flying!
/^v^\
/^v^\ /^v^\
/^v^\
/^v^\
Flap flap!
\^v^/
\^v^/ \^v^/
\^v^/
\^v^/
Wow wow An Archer!
/\
/__\_{)
|--<<)__\
\ / (
\/ )
/|
\ \
~ ~
/| \
/_|_{)/
---<< | | )
\ | (
\| )
/|
\ \
~ ~
\
/|{)/
---<< +-|-)
\| (
)
/|
\ \
~ ~
/\
/__\_{)
|--<<)__\
\ / (
\/ __)
\ |__
~ ~
/| \
/_|_{)/
---<< | | )
\ | (
\|__)
\ |__
~ ~
\
/|{)/
---<< +-|-)
\| (
__)
\ |__
~ ~
Super Cyclist
---------- __o
-------- _ \<,_
------- (*)/ (*)
Wheeeee!
Flying a Kite
/\
'\/
' +
' +
' +
' +
' +
' +
'
'
'
'
'
'
'
'
__ '
\o . '
\\/
/\
/ /
This fishing one is pretty hillarious as well
http://asciimator.net/kangaroo/fishing.html
In Javascript using one jQuery selectors:
var spins = [
"←↖↑↗→↘↓↙",
"▁▃▄▅▆▇█▇▆▅▄▃",
"▉▊▋▌▍▎▏▎▍▌▋▊▉",
"▖▘▝▗",
"┤┘┴└├┌┬┐",
"◢◣◤◥",
"◰ ◳ ◲ ◱",
"◴◷◶◵",
"◐◓◑◒",
"|/-\\"];
var spin = spins[0],
title$ = $('title'),
i=0;
setInterval(function() {
i = i==spin.length-1 ? 0 : ++i;
title$.text('('+ spin[i] +') Loading...');
},300);
I'm glad I'm not the only one crazy enough to waste time on this!
Here are my favourites (some using dos ascii codes):
classic: "/-\\|";
bouncing ball: ".oOo";
better bouncing ball: [46, 111, 79, 248, 79, 111]; // (.oO°Oo.)
[180, 217, 193, 192, 195, 218, 194, 191]; // ┤ ┘ ┴ └ ├ ┌ ┬ ┐
[185, 188, 202, 200, 204, 201, 203, 187]; // double piped version of that
[219, 220, 223]; // block colours
Makes a cute "rain" effect:
using System;
using System.Text;
using System.Threading;
namespace CSharpSandbox
{
class Program
{
static Random rnd = new Random();
static char[,] Step(char[,] matrix)
{
int width = matrix.GetUpperBound(0) + 1;
int height = matrix.GetUpperBound(1) + 1;
char[,] res = new char[width, height];
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
char c;
if (h == 0)
c = rnd.Next(2) == 0 ? ' ' : '*';
else
c = matrix[w, h - 1];
res[w, h] = c;
}
}
return res;
}
static string ToString(char[,] matrix)
{
int width = matrix.GetUpperBound(0) + 1;
int height = matrix.GetUpperBound(1) + 1;
StringBuilder sb = new StringBuilder();
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
sb.Append(matrix[w, h]);
}
sb.AppendLine();
}
return sb.ToString();
}
static Timer timer;
static void Spinner()
{
char[,] matrix = new char[10, 5];
timer = new Timer(_ =>
{
string s = ToString(matrix);
Console.SetCursorPosition(0, 0);
Console.Write(s);
matrix = Step(matrix);
},
null,
0,
200);
}
static void Main(string[] args)
{
Spinner();
Console.ReadLine();
}
}
}
In one application, I saw 1,2,3,4,5,6,7,8,9,0.
Courtesy of a co-worker of mine, here's a nifty implementation in C:
#define COW 2172
char* moo = "MO ";
void wrap() {
int i,j;
for(i=0;doSomething(i);i++)
j=COW-moo[i&3],fputs(&j,stderr);
}
From my analysis, it only works on a little-endian machine with at least 32-bit words and the ASCII character set. But it's rather diabolically clever.
I wrote one that cycled through the standard \ | / - but the left a _ and moved on to the next position. It was intended to look as though there were a series of spinners, each dropping to the floor before the next one started. The need for this was that my program was repeatedly trying something and waiting for a certain result. I wanted to represent each time it tried and also how many times it had tried without using up a lot of screen space (or count).
After I wrote it it looked a lot less cool than I thought it would, but it served its purpose.
I have seen
echo -e "\033[41;1m$1 \033[0m"
In bash to continually build a progress bar based on a block character.

Resources