Bash 中的多個 sed 指令

Bash 中的多個 sed 指令

我有一個 JSON 格式的檔案使用者名稱和密碼,我想將其轉換為進程。

我已經使用了sed不同的命令來處理它,但我想知道的是如何將所有三個命令合併為一個以供將來使用。

原始格式

    { "user.name1" : "hashed_password",
"user.name2" : "hashed_password" }

所需輸出

user.name:hashed_password

這些是我運行的命令,但是我無法使用管道將它們鏈接在一起,或者只是在出現錯誤的地方將它們連接起來sed: -e expression #1, char 8: unknown option to 's'

違規指令...

sed -i 's/\"//g/s/\,/\n/g/\s//g' input_file 
sed: -e expression #1, char 8: unknown option to `s'

如何將以下命令連接成一個?

指令刪除雙引號

sed -i 's/\"//g' input_file

用新行替換逗號

sed -i 's/\,/\n/g' input_file

刪除空格

sed -i 's/\s//g input_file

答案1

將多個sed命令放在一個“腳本”,您可以使用多個-e標誌(這是可移植的):

sed -i -e 's/\"//g' -e 's/\,/\n/g' -e 's/\s//g' input_file

或分號分隔符號(並非在所有實作上都可用):

sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file

您還需要添加對大括號的處理 - {}...


話雖如此,要正確解析和處理 JSON,您不應該真正使用sed...也許嘗試jq

jq -r 'keys[] as $k | "\($k):\(.[$k])"' input_file

輸出:

user.name1:hashed_password
user.name2:hashed_password
  • keys[] as $k將迭代每個鍵,將其值儲存在$k
    • IE:user.name1user.name2
  • "\($k):\(.[$k])"將形成一個字串,替換為$kand.[$k]
  • 使用-r從輸出字串中刪除引號(生的模式)

使用sedJSON 來處理會給你帶來各種各樣的問題......例如,你將如何處理以下(完全有效的 JSON)輸入?

{
    "user.name1" :
        "hashed_password",
    "user.name2" :
        "hashed_password"
}

答案2

當您處理 JSON 等標準化輸入時,通常最好使用適當的解析器而不是正規表示式。例如,您將正確轉換任何轉義序列(儘管對於您的特定輸入資料來說這可能是不可能的!)。

不幸的是,coreutils 中沒有用於處理 JSON 的優秀工具。阿蒂提供 jq如果您可以自由安裝軟體包,這是一個不錯的選擇。

如果您無法安裝其他軟體包,那麼在 Python 中這並不是特別困難。以這個腳本為例:

import json,sys
for (k, v) in json.load(sys.stdin):
    print(k + ":" + v)

可以將其壓縮為一行:

cat inputdata | python -c 'import json,sys;print("\n".join((k + ":" + v) for (k, v) in json.load(sys.stdin).items()))'

答案3

對於您在這些命令中執行的簡單字符刪除,sed我建議您使用tr,其唯一目的是刪除、壓縮或替換單個字符,包括換行符(sed基於正則表達式,通常依賴換行符作為緩衝區分隔符,所以使用sed 修改換行符很棘手)。我認為這個tr命令可以完成您正在尋找的一切:

cat json_filename | tr -d "{}\" \012\011\015" | tr "," "\012"

第一個指令tr刪除所有大括號、雙引號、空格、回車符(八進位 012、ascii 10)、製表符(八進位 011、ascii 9)和換行符號(八進位 015、ascii 13)。tr將所有逗號替換為只要 JSON 檔案的變數名稱和值不包含逗號,這些命令就可以讓您避免需要專用的 JSON 解析器。

也就是說,如果您有一組各自獨立工作的命令,則使用“-f”選項從檔案中讀取單獨的命令sed可以最輕鬆地組合它們。sed您只需將 s/.../.../g 字串放入一個檔案中,每個字串佔一行,然後在「-f」選項後面指定該檔案名稱。例如,如果sed您列出的三個命令令人滿意,您可以將它們放入名為「json.convert.sed」的檔案中,該檔案僅包含以下內容:

s/\"//g 
s/\,/\n/g
s/\s//g

然後您可以sed使用以下命令調用此命令檔案:

sed -f json.convert.sed

也就是說,這些sed命令無法幫助我完成您想要的任務,而且我不確定您是否可以sed修改換行符。這是因為sed它基於舊的“ed”行編輯器,設計用於一次編輯單行(它的“腳本”版本),因此每行輸入都使用換行符作為分隔符“解析”,然後該行(不帶換行符)被傳遞到編輯引擎,應用編輯命令,然後編輯後的行會帶有換行符輸出。然後循環重複。我只能sed透過先使用 . 將換行符更改為某個不同的字元(否則不會出現在輸入中)來修改換行符trtr如果您只想刪除換行符,那麼使用這種方式是沒有意義的,因為tr它將為您做到這一點。但是,例如,如果您想將換行符號轉換為帶有尾隨空格的分號,一種方法是:

cat input_file | tr "\012" "%" | sed "s/%/; /g"

(換行符透過 轉換為 % tr,然後sed將所有 % 字元轉換為「;」字元對。)

答案4

你可以這樣組合它:

sed -i 's/\"//g;s/\,/\n/g;s/\s//g' input_file

您忘記新增刪除{}.所以你可能想要:

sed -i 's/\"//g;s/\,/\n/g;s/\s//g;s/{//g;s/}//g' input_file

相關內容