Posso fazer um grep para 2 pattterns e tê-los listados lado a lado?

3

Ubuntu 16.04
bash -version
GNU bash, versão 4.4.0 (1) -release (x86_64-unknown-linux-gnu)

Eu gostaria de fazer um grep para dois padrões e depois listá-los lado a lado. ATM, é isso que eu tenho:

root@tires ~ # grep -e tire_id -e appID /path/to/*/vehicle/production.json
/path/to/000001_000002/vehicle/production.json:    "tire_id": "1305436516186552",
/path/to/000001_000002/vehicle/production.json:        "appID": "1164562920689523",
/path/to/000001_000079/vehicle/production.json:    "tire_id": "1815123428733289",
/path/to/000001_000079/vehicle/production.json:        "appID": "18412365908966538",
/path/to/000001_000088/vehicle/production.json:    "tire_id": "138477888324",

É isso que eu gostaria de ter ou qualquer coisa semelhante funcionaria na verdade.

root@tires ~ # grep -e tire_id -e appID /path/to/*/vehicle/production.json
/path/to/000001_000002/vehicle/production.json:    tire_id: 1305436516186552, appID: 1164562920689523
/path/to/000001_000079/vehicle/production.json:    tire_id: 1815123428733289, appID: 18412365908966538

Exemplo de arquivo aqui:

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "213275925375485",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": XXXX,
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "233262274090443",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD",
    },
    "attachments": {
        "output": "attachments",
        "public": false,
    },
}
    
por needtoknow 12.07.2018 / 17:19

4 respostas

11

O caminho certo com a ferramenta jq para documentos JSON válidos:

Amostra file1.json :

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "213275925375485",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": "XXXX",
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "233262274090443",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD"
    },
    "attachments": {
        "output": "attachments",
        "public": false
    }
}

Amostra file2.json :

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "1305436516186552",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": "XXXX",
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "1164562920689523",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD"
    },
    "attachments": {
        "output": "attachments",
        "public": false
    }
}

E a solução em si:

jq -r 'input_filename + " tire_id: \(.tire_id) appID: \(.cdc.appID)"' file*.json

A saída:

file1.json tire_id: 213275925375485 appID: 233262274090443
file2.json tire_id: 1305436516186552 appID: 1164562920689523
    
por 12.07.2018 / 18:37
1

Você pode fazer isso com grep , mas é bastante complicado e a resposta de Roman é realmente melhor.

Seu conteúdo de exemplo é apenas de um arquivo, portanto, há apenas uma instância de tire_id e appID .

Use isto:

echo $(echo /path/to/production.json && egrep "tire_id|appID" /path/to/production.json | sed -e 's|"||g' | sed -e 's|,||2') && echo $(echo /path/to/production2.json && egrep "tire_id|appID" /path/to/production2.json ) | sed -e 's|"||g' | sed -e 's|,||2'

echo coloca tudo na mesma linha com a substituição de comando.

egrep faz a mesma coisa que grep -e , mas permite que você coloque todas as strings juntas separadas por | em vez de ter que usar -e string de cada vez.

sed -e 's|"||g' remove os apóstrofos.

sed -e 's|,||2 remove a vírgula do final do valor de appID , que é o que é mostrado na saída desejada.

Saída:

/path/to/production.json tire_id: 213275925375485 appID: 233262274090443
/path/to/production2.json tire_id: 1815123428733289 appID: 18412365908966538

/path/to/production.json e /path/to/production2.json são apenas marcadores de posição.

Isso obviamente requer muitas modificações, já que você teria que grep cada arquivo separadamente e usar uma substituição de comando echo para cada um. Eu só estou incluindo se você insistir em usar grep ou se, no futuro, não for um arquivo json .

    
por 12.07.2018 / 18:36
0

Com um script sed:

grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n '/\(.*:\)/h;n;s/.*n://;H;g;s/\n//;p'

Retrun

/path/to/000001_000002/vehicle/production.json:    "tire_id": "1305436516186552",        "appID": "1164562920689523",
/path/to/000001_000079/vehicle/production.json:    "tire_id": "1815123428733289",        "appID": "18412365908966538",
/path/to/000001_000088/vehicle/production.json:    "tire_id": "138477888324",

funciona se cada linha "tire_id" for seguida por uma linha "appID". Caso contrário, você precisa de um script sed mais complexo

    
por 12.07.2018 / 20:17
0

Esse comando funcionará mesmo se em um arquivo não houver uma linha "tire_id" ou "appID". Não será exibido:

grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n 's/\(tire_id\)//;T;h;n;s/.*n:.*\(appID\)//;T;H;g;s/\n/ /;s/"//g;s/,//g;p'
    
por 12.07.2018 / 23:39

Tags