Bash
兩次處理相同的標準輸入並附加輸出
我有一個 json 文件,看起來像:
[ { "key": "alt+down", "command": "-editor.action.moveLinesDownAction", "when": "editorTextFocus && !editorReadonly" }, { "key": "alt+f12", "command": "editor.action.peekDefinition", "when": "editorHasDefinitionProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor" } ] // { // "key": "ctrl+shift+d", // "command": "workbench.action.toggleMaximizedPanel" // }, // { // "key": "ctrl+shift+d", // "command": "-workbench.view.debug", // "when": "viewContainer.workbench.view.debug.enabled" // }
我想對這個文件進行排序。
jq
如果行首有錯誤,則給出錯誤//
,因為這不是有效的 json。所以要對這個文件進行排序,我想出的命令是:
grep -v '^[ ]*//' keybindings.json | jq 'sort_by(.key)'
但我不想丟棄註釋行。因此,要獲得註釋行,我想出的命令是:
grep '^[ ]*//' keybindings.json
現在要解決我的問題,我可以簡單地做的是:
#!/bin/bash SORTED_JSON=$(grep -v '^[ ]*//' keybindings.json | jq 'sort_by(.key)') COMMENTED_JSON=$(grep '^[ ]*//' keybindings.json) echo "$SORTED_JSON" >keybindings.json echo "$COMMENTED_JSON" >>keybindings.json
但是有一個問題!
我必須在一個命令中執行此操作。這是因為,我是通過 vscode 設置來做到這一點的。
"filterText.commandList": [ { "name": "Sort VSCode Keybindings", "description": "Sorts keybindings.json by keys. Select everything except the comment in fist line. Then run this command", "command": "jq 'sort_by(.key)'" } ]
將
command
選中的文本作為標準輸入,進行處理,然後輸出處理後的文本。所以,據我所知,我必須兩次閱讀標準輸入(一次
grep -v '^[ ]*//' | jq 'sort_by(.key)'
和第二次grep '^[ ]*//'
)。並將兩個命令輸出附加到標準輸出中。我怎麼解決這個問題?
更新1:
我都試過了
cat keybindings.json| {grep -v '^[ ]*//' | jq 'sort_by(.key)' ; grep '^[ ]*//'}
和
cat keybindings.json| (grep -v '^[ ]*//' | jq 'sort_by(.key)' ; grep '^[ ]*//')
這些不顯示註釋行。
更新 2:
以下似乎接近我的預期。但是這裡註釋的行位於未註釋的行之前。
$ cat keybindings.json| tee >(grep -v '^[ ]*//' | jq 'sort_by(.key)') >(grep '^[ ]*//') > /dev/null 2>&1 // { // "key": "ctrl+shift+d", // "command": "workbench.action.toggleMaximizedPanel" // }, // { // "key": "ctrl+shift+d", // "command": "-workbench.view.debug", // "when": "viewContainer.workbench.view.debug.enabled" // } [ { "key": "alt+down", "command": "-editor.action.moveLinesDownAction", "when": "editorTextFocus && !editorReadonly" }, { "key": "alt+f12", "command": "editor.action.peekDefinition", "when": "editorHasDefinitionProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor" } ]
更新 3:
cat keybindings.json| (tee >(grep '^[ ]*//'); tee >(grep -v '^[ ]*//' | jq 'sort_by(.key)'))
或者,
cat keybindings.json| {tee >(grep '^[ ]*//'); tee >(grep -v '^[ ]*//' | jq 'sort_by(.key)')}
似乎也提供與更新 3 相同的輸出(註釋行位於未註釋行之前)。
我知道沒有辦法插入混合註釋行和非註釋行;您必須將它們視為單獨的塊並單獨處理它們。
如果您不介意首先輸出註釋行,則可以這樣使用
awk
:awk '{ if ($0 ~ /^ *\/\//) { print } else { print | "jq \"sort_by(.key)\"" } }' keybindings.json
但是由於您希望註釋行出現在最後,您需要儲存註釋行並稍後輸出:
awk ' # Define a convenience variable for the jq process BEGIN { jq = "jq \"sort_by(.key)\"" } # Each line hits this. Either we save the comment or we feed it to jq { if ($0 ~ /^ *\/\//) { c[++i] = $0 } else { print | jq } } # Close the pipe to get its output and then print the saved comment lines END { close (jq); for (i in c) { print c[i] } } ' keybindings.json
現在,關於您的“我必須在一個命令中執行此操作”。請記住,沒有什麼能阻止您創建自己的命令(程序、腳本)。將必要的命令集放入文件中,使文件可執行,然後將其放入
$PATH
. 我一直使用and 我在我的and中$HOME/bin
有等價物。export PATH="$PATH:$HOME/bin"``~/.bash_profile``~/.profile