乌班图16.04
bash -version
GNU bash, version 4.4.0(1)-release (x86_64-unknown-linux-gnu)
我想要grep
两种模式,然后将它们并排列出。目前,这就是我所拥有的:
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",
这就是我想要的,尽管任何类似的东西实际上都会起作用。
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
文件示例在这里:
{
"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,
},
}
答案1
正确的方法是与jq
有效 JSON 文档的工具:
样本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
}
}
样本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
}
}
以及解决方案本身:
jq -r 'input_filename + " tire_id: \(.tire_id) appID: \(.cdc.appID)"' file*.json
输出:
file1.json tire_id: 213275925375485 appID: 233262274090443
file2.json tire_id: 1305436516186552 appID: 1164562920689523
答案2
你可以这样做,grep
但它相当复杂,罗马的答案实际上更好。
您的示例内容仅来自一个文件,因此只有一个tire_id
和实例appID
。
用这个:
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
通过命令替换将所有内容放在同一行。
egrep
与 执行相同的操作grep -e
,但允许您将所有字符串分隔在一起,|
而不必-e string
每次都使用。
sed -e 's|"||g'
删除撇号。
sed -e 's|,||2
appID
从所需输出中显示的值末尾删除逗号。
输出:
/path/to/production.json tire_id: 213275925375485 appID: 233262274090443
/path/to/production2.json tire_id: 1815123428733289 appID: 18412365908966538
/path/to/production.json
并且/path/to/production2.json
只是占位符。
这显然需要大量修改,因为您必须单独 grep 每个文件并echo
为每个文件使用命令替换。仅当您坚持使用grep
或者将来它不是文件时,我才会包含它json
。
答案3
使用 sed 脚本:
grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n '/\(.*:\)/h;n;s/.*n://;H;g;s/\n//;p'
重播
/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",
如果每行“tire_id”后面跟着一行“appID”,它就可以工作。否则,您需要更复杂的 sed 脚本
答案4
即使在文件中缺少“tire_id”或“appID”行,此命令也将起作用。它不会显示:
grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n 's/\(tire_id\)/\1/;T;h;n;s/.*n:.*\(appID\)/\1/;T;H;g;s/\n/ /;s/"//g;s/,//g;p'