exemplo mágico usando pesquisa e / ou regex

3

Estou tentando que o comando file detecte alguns arquivos de texto do Windows que nunca foram classificados como arquivos ... A melhor opção parece usar o regex para corresponder ao conteúdo da linha, mas não consigo encontrar um único exemplo de seu uso (a comunalidade das palavras-chave 'file', 'magic' e 'regex' não ajuda em um mundo centrado no google). A página man não ajuda.

Além disso, não consigo fazer com que o ^ $ funcione.

Ambos os arquivos começam com

Project Units: <stuff>
Units & Scale - <stuff>
<blank line>

Próxima linha é um cabeçalho que começa 4a) ID do objeto, foto #, 4b) Id, nome,

Minha tentativa de regras mágicas para isso é:

0  string Project0Units:
>2 regex ^Object0point0ID,Photo0#, PhotoModeler 2D export table

0  string Project0Units:
>2 regex ^Id,Name, PhotoModeler 3D export table

i.e. match 'Project Units:' na primeira linha, então faça uma tentativa de regex de no máximo 2 + 1 linhas. Âncora regex para início de linha para velocidade.

Isso está no Ubuntu 14.04, arquivo-5.14.

Exemplo de tipo de arquivo 1 (apenas 10 linhas):

Project Units: meters
Units & Scale - Active, Translate - Active, Rotate - Active

Object Point ID,Photo #,X (pixels),Y (pixels),Residual X,Residual Y,Residual Vector,Mark Type,Layer,Material,Tagged
2,1,1429.187065,1456.427823,-0.164541,0.182824,0.245964,LSM Circular,Default,White, 
2,2,666.583514,1126.807078,-0.168174,0.109780,0.200833,LSM Circular,Default,White, 
2,3,716.264669,1196.788962,0.152059,0.082258,0.172882,LSM Circular,Default,White, 
2,4,674.145595,442.969428,0.119315,-0.050084,0.129401,LSM Circular,Default,White, 
2,5,330.056929,836.292587,0.048372,-0.022235,0.053238,LSM Circular,Default,White, 
2,6,1147.101715,39.253316,0.475434,-0.189514,0.511814,LSM Circular,Default,White, 

Exemplo de tipo de arquivo 2 (apenas 10 linhas):

Project Units: meters
Units & Scale - Active, Translate - Active, Rotate - Active

Id,Name,Photos (used),X (project units),Y (project units),Z (project units),X Precision,Y Precision,Z Precision,Precision Vector Length,Tightness (percent),Tightness (project units),Angle (deg.),Control Name,RMS Residual (pixels),Largest Residual (pixels),Photo Largest Residual,Material,Layer,Tagged,Type,Use In Processing,Frozen,#Constraints,Target Code,Target Bits,Ref. Check Tag,Photos (marked),Color (R),Color (G),Color (B)
2," ","1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.285721,1.143037,-0.000990,0.000044,0.000043,0.000075,0.000097,0.037511,0.000682,85.604862, ,0.261467,0.511814,6,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
3," ","1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.428622,1.143108,-0.000230,0.000044,0.000042,0.000074,0.000096,0.033814,0.000615,86.326354, ,0.222883,0.475602,6,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
4," ","1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.142979,1.143124,-0.000840,0.000045,0.000044,0.000078,0.000100,0.030045,0.000546,84.468461, ,0.239445,0.374918,16,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
5," ","1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.571353,1.143164,0.000784,0.000044,0.000042,0.000074,0.000096,0.027194,0.000494,86.593419, ,0.213540,0.430629,6,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
6," ","1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.000141,1.143101,-0.000885,0.000046,0.000045,0.000081,0.000103,0.035513,0.000646,82.937166, ,0.291437,0.465014,16,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
7," ","1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",0.714058,1.143134,0.000247,0.000044,0.000043,0.000075,0.000097,0.030057,0.000547,86.326626, ,0.221009,0.426056,6,White,Default, ,Regular,yes,no,0,n/a,n/a, ,"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21",255,255,255
    
por Niclas Börlin 22.06.2016 / 11:08

2 respostas

2

O arquivo file (1) apenas informa como executar o comando. Para uma descrição dos padrões mágicos, veja magia (5) . No entanto, a seção sobre regex não é especialmente detalhada. Uma grande variedade de exemplos de seu uso pode ser encontrada nos arquivos padrão que vêm com ele: link

Seu principal problema é que o cursor precisa ser salvo: \^ para o início da linha, \^ para o literal ^ . Eu não trabalhei com o significado especial que o ^ sem escape tem. Espaços também podem ser escapados, tornando o padrão um pouco mais legível.

Você pretende restringir a correspondência a um intervalo de linhas estreitas. regex usa a opção /<length> (depois da palavra regex , não depois do padrão), de modo que coloca um limite de onde a pesquisa termina . Se o comprimento for seguido por um l , isso significa linhas em vez de bytes. Em meus testes, /1l só pode corresponder a uma linha vazia - uma linha não vazia, mesmo quando se usa o deslocamento inicial exato, requer pelo menos /2l .

Para o início da pesquisa, offset é interpretado como uma contagem de bytes, mesmo com regex . (Pré-versão 5.19, a documentação sugere que ela é interpretada como uma "contagem de linhas", mas essa declaração foi removida sem alteração de código correspondente, por isso duvido que seja preciso mesmo antes disso.) Poderia utilizar o desvio &0 para iniciar a pesquisa a partir do final do jogo anterior, mas isso não fará muita diferença quando o jogo anterior terminou no meio da primeira linha.

Além disso, "início da linha" também corresponde a "início do intervalo de pesquisa" (ou seja, de offset ), independentemente de ter sido o início de uma linha no arquivo.

Então, para combinar as coisas mais estritamente, você pode usar um regexp de linha completa em todas as linhas e usar o deslocamento &1 na próxima partida, para ignorar a nova linha anterior e estar no lugar certo para a \^ para trabalhar como esperado. Isso pode ser um exagero para identificar seus tipos de arquivo personalizados.

Finalmente, você não precisa repetir as partes comuns. O nível de > indentação significa que um padrão deve ser tentado quando os padrões anteriores no mesmo nível falharem.

Juntando tudo isso:

0       regex/2l        \^Project\ Units:.*$
>&1     regex/2l        \^Units\ &\ Scale.*$
>>&1    regex/1l        \^$
>>>&1   regex/2l        \^Object\ Point\ ID     Photo Modeler 2D export table   
>>>&1   regex/2l        \^Id,Name,Photos        Photo Modeler 3D export table
    
por 22.06.2016 / 22:28
2

Uma solução foi devido a @JigglyNaga - escapar do cursor. O snippet abaixo agora faz parte do meu arquivo .magic.

0   string  Project0Units:
>2  regex   \^Id,  PhotoModeler 3D export table

0   string  Project0Units:
>2  regex   \^Object0Point0ID,  PhotoModeler 2D export table
    
por 22.06.2016 / 15:04