Điểm:-1

Cách trích xuất một chuỗi từ tệp json và đặt vào một biến (Linux)

lá cờ us

Tôi có phần sau trong một trong các tệp json của mình file1.json: -

{
  "$quer": {
    "đối số": [{
      "đối số": [
        "chọn\n db1.table1 làm tab1,\n db1.table2 làm tab2,\n db1.table3 làm tab3\n từ db1.table4 làm tab4"
      ],
      "fn": "từ-sql",
      "ns": "op"
    }],
    "fn": "toán tử",
    "ns": "op"
  }
}

Tôi muốn trích xuất chuỗi db1.table4 từ tệp json này và lưu vào một biến.

Tôi không biết nhiều về sed và awk. Ai đó có thể giúp đỡ ở đây?

terdon avatar
lá cờ cn
Làm thế nào chúng ta có thể biết những gì để trích xuất? Nó có phải luôn là từ thứ hai từ phần tử đầu tiên trong mảng `args` không? Nó có nên là bất cứ thứ gì sau `select\n` không? Làm cách nào chúng tôi có thể xác định phần tệp bạn muốn giải nén?
Điểm:2
lá cờ us
  1. Giả sử rằng chuỗi bạn muốn trích xuất đứng ở cùng một vị trí trong mọi tệp bạn có thể sử dụng cái đầu, đuôicắt tỉa lệnh sử dụng đường ống.

  2. Ví dụ:

    $ đầu -6 tệp.json | đuôi -1 | cắt -b 121-129
    db1.table
    
  3. Và đây là một ví dụ về tập lệnh đặt đầu ra thành một biến:

    #!/bin/bash
    v1=$(head -6 file.json | tail -1 | cut -b 121-130)
    tiếng vang "$v1"
    

Đầu ra của tập lệnh sẽ là db1.table4 đó là giá trị của V1 khả biến.

Bạn có thể đọc thêm về các lệnh đó tại đây:

Tất nhiên, bạn có thể sử dụng các lệnh đó để trích xuất bất kỳ chuỗi nào khác từ một tệp.

Aviator avatar
lá cờ us
cảm ơn rất nhiều. Nó đã giúp đỡ tôi.
Điểm:2
lá cờ ru

Hãy xem tại jq bộ xử lý JSON dòng lệnh, cài đặt ví dụ với:

sudo apt cài đặt jq

Chuỗi bạn muốn không phải là giá trị JSON, nó là một phần của giá trị JSON. Vì vậy, tôi đề nghị bạn sử dụng jq để lấy chuỗi bạn cần thao tác thành biến, ví dụ:

my_var=$(jq -r .[$quer].args[0].args[0] file1.json)

Điều này giúp bạn có một biến chứa câu lệnh SELECT:

chọn db1.table1 làm tab1, db1.table2 làm tab2, db1.table3 làm tab3 từ db1.table4 làm tab4

Sau đó, bạn sẽ cần sử dụng các công cụ khác như sed, awk, cut, v.v. để lấy chuỗi con bạn muốn từ biến đó. Đối với trường hợp cụ thể của bạn, điều này sẽ hoạt động nhưng tất nhiên có thể không hoạt động đối với một câu lệnh CHỌN khác. Cắt bằng dấu cách và trả về giá trị thứ 12:

my_table=$(echo $my_var | cut -d' ' -f12)
Aviator avatar
lá cờ us
nó đã có rồi nhưng câu hỏi của tôi không liên quan đến việc sử dụng lệnh unix.
terdon avatar
lá cờ cn
@Aviator `jq` _is_ một lệnh, giống như bất kỳ lệnh nào khác. Nó chỉ là công cụ phù hợp để sử dụng khi phân tích cú pháp các tệp json.
codlord avatar
lá cờ ru
Các ví dụ đã thêm ở trên.
terdon avatar
lá cờ cn
Cảm ơn! Điều đó rõ ràng hơn nhiều :)
Điểm:1
lá cờ cn

Nói chung, bạn nên tránh sử dụng các công cụ phân tích cú pháp văn bản chung cho dữ liệu có cấu trúc. Vì bạn có tệp json nên việc sử dụng trình phân tích cú pháp json chuyên dụng sẽ an toàn và đơn giản hơn. Trong trường hợp của bạn, bạn muốn trích xuất giá trị của phần tử đầu tiên của mảng tranh luận chính nó là phần tử đầu tiên của mảng cấp cao nhất tranh luận, con của hàm băm cấp cao nhất $quer:

$ jq '."$quer",."args"[0]["args"]' file.json
[
  "chọn\n db1.table1 làm tab1,\n db1.table2 làm tab2,\n db1.table3 làm tab3\n từ db1.table4 làm tab4"
]

Từ đây, bạn không còn dữ liệu có cấu trúc nữa và bạn cần sử dụng các phương pháp thô sơ hơn. Tôi không biết bạn muốn xác định chuỗi mục tiêu của mình như thế nào, bạn đã không giải thích điều đó. Vì vậy, tùy thuộc vào những gì bạn thực sự muốn, bạn có thể làm:

  1. Bỏ qua các dòng bắt đầu bằng [ hoặc ] và sau đó in từ thứ hai của các dòng còn lại:

    $ jq '."$quer".."args"[0]["args"]' file.json | awk '/^[^][]/{in $2}'
    db1.table1
    
  2. In từ thứ hai của dòng thứ hai

    $ jq '."$quer".."args"[0]["args"]' file.json | awk 'NR==2{in $2}'
    db1.table1
    
  3. In đoạn dài nhất không có khoảng trắng sau chuỗi "chọn\n:

    $ jq '."$quer".."args"[0]["args"]' file.json | grep -oP '"chọn\n\s*\K\S*'
    db1.table1
    

Nếu bạn giải thích chính xác cách chúng tôi phải biết chuỗi nào cần trích xuất, tôi có thể cung cấp cho bạn câu trả lời có mục tiêu hơn.


Để hoàn thành, trong của bạn cụ thể và tôi nhấn mạnh rằng điều này sẽ không khả dụng và gần như chắc chắn sẽ thất bại nếu dữ liệu đầu vào của bạn thay đổi theo bất kỳ cách nào, bạn có thể sử dụng trực tiếp các công cụ văn bản đơn giản:

$ grep -oP '"chọn\n\s*\K\S*' file.json 
db1.table1

$ awk '$1=="\"select\n"{print $2}' file.json 
db1.table1

$ sed -nE 's/.*"select\n\s*(\S+).*/\1/p' file.json 
db1.table1
lá cờ hr
Bạn có thể thực hiện một số thao tác cắt giống như awk trong jq, ví dụ `jq -r '."$quer".args[0].args[] | tách("\n")[-1] | split(" ")[-3]' file.json` hoặc có thể là thứ gì đó dựa trên biểu thức chính quy như `jq -r '."$quer".args[0].args[] | nắm bắt ("từ (?[^ ]+)") | .a'`
terdon avatar
lá cờ cn
@steeldriver vâng, nhưng tôi đoán rằng vì tôi không biết OP thực sự muốn trích xuất cái gì, nên tôi cũng có thể đưa ra một số lựa chọn đơn giản.
lá cờ hr
thực sự ... không rõ ràng

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.