Bash

搜尋模式並創建同名文件

  • October 26, 2021

這是我的一個簡單的用法:

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

序列化對象可以使用@jsonin 運算符創建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"}

引用自:https://unix.stackexchange.com/questions/674732