Bash
搜尋模式並創建同名文件
這是我的一個簡單的用法:
grep -i '"location_country":"country name"' file.txt >> sample.txt
我正在搜尋一個包含多個國家/地區的大文件,我想做的是動態創建一個帶有國家名稱的文本文件,並將來自同一國家的所有匹配項儲存到該文件中,這意味著
country name.txt
每次出現。像這樣的東西
grep -i '"location_country":"(.+)"' file.txt >> \1.txt
數據範例:
{"full_name":"name1","location_country":"united kingdom"} {"full_name":"name2","location_country":"united states"} {"full_name":"name3","location_country":"china"}
所以我需要創建 3 個帶有國家名稱的單獨文本文件,例如
united kingdom.txt
包含:{"full_name":"name1","location_country":"united kingdom"}
我已經在使用 bash 腳本,所以我不介意,我怎麼能做到這一點?我正在使用 Linux 機器。
您的文件由一組 JSON 對象組成。每個對像都包含一個
.location_country
鍵。我們可以從每個對象創建一個 shell 命令,將對象本身的序列化副本寫入由.location_country
鍵值命名的文件。然後這些shell 命令可以由shell 執行。使用
jq
,jq -r '"printf \"%s\\n\" \(. | @json | @sh) >\(.location_country|@sh).txt"' file.txt
序列化對象可以使用
@json
in 運算符創建jq
,它將發出包含輸入文件的 JSON 編碼字元串,在本例中為目前對象。然後將其饋入@sh
以正確引用 shell 的字元串。該@sh
運算符還用於根據.location_country
鍵的值創建部分輸出文件名。該命令本質上創建的 shell 程式碼將呼叫
printf
、輸出目前對象並將輸出重定向到特定文件。鑑於您在 中的範例數據
file.txt
,這將發出以下內容:printf "%s\n" '{"full_name":"name1","location_country":"united kingdom"}' >'united kingdom'.txt printf "%s\n" '{"full_name":"name2","location_country":"united states"}' >'united states'.txt printf "%s\n" '{"full_name":"name3","location_country":"china"}' >'china'.txt
您可以將其重定向到一個單獨的文件並執行它
sh
以執行命令,或者您可以eval
直接在 shell 中使用:eval "$( jq ...as above... )"
由於我們使用的是正確的 JSON 解析器,
jq
因此即使輸入的 JSON 文件沒有使用每行單個對象進行格式化,上述方法也可以工作。$ cat file.txt { "full_name": "name1", "location_country": "united kingdom" } { "full_name": "name2", "location_country": "united states" } { "full_name": "name3", "location_country": "china" }
$ jq -r '"printf \"%s\\n\" \(. | @json | @sh) >\(.location_country|@sh).txt"' file.txt printf "%s\n" '{"full_name":"name1","location_country":"united kingdom"}' >'united kingdom'.txt printf "%s\n" '{"full_name":"name2","location_country":"united states"}' >'united states'.txt printf "%s\n" '{"full_name":"name3","location_country":"china"}' >'china'.txt
$ eval "$( jq -r '"printf \"%s\\n\" \(. | @json | @sh) >\(.location_country|@sh).txt"' file.txt )" $ ls china.txt file.txt united kingdom.txt united states.txt $ cat 'united kingdom.txt' {"full_name":"name1","location_country":"united kingdom"}