Bash:从带引号的字符串块中的每个带引号的字符串创建一个变量
Bash: Make a Variable out of Each Quoted String in a Block of Quoted Strings
我正在尝试编写一个脚本来遍历 Keyboard Preference Pane
的 Shortcuts > Services
部分中的每项服务并将其禁用。
这是禁用服务的基本命令:
defaults write pbs NSServicesStatus -dict-add SERVICE "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
"
预先获取所有服务并将它们放在脚本中是低效的,因为许多服务是在安装新软件时逐渐添加的。它必须是某种循环。
到目前为止,我一直在尝试使用 defaults
和 awk
来获取包含服务的每一行。
a=$(defaults read pbs NSServicesStatus | awk 'NR%5==2' ) && echo $a
而且,这是输出:
"com.ScooterSoftware.BeyondCompare - Compare Files - bcCompareFiles" = { "com.ScooterSoftware.BeyondCompare - Compare Folders - bcCompareFolders" = { "com.ScooterSoftware.BeyondCompare - Select Left File for Compare - bcSelLeftFile" = { "com.ScooterSoftware.BeyondCompare - Select Left Folder for Compare - bcSelLeftFolder" = { "com.apple.BluetoothFileExchange - Send File To Bluetooth Device - sendFileUsingBluetoothOBEXService" = { "com.apple.ChineseTextConverterService - Convert Text from Simplified to Traditional Chinese - convertTextToTraditionalChinese" = { "com.apple.ChineseTextConverterService - Convert Text from Traditional to Simplified Chinese - convertTextToSimplifiedChinese" = { "com.apple.ChineseTextConverterService - Convert Text to Full Width - convertTextToFullWidth" = { "com.apple.ChineseTextConverterService - Convert Text to Half Width - convertTextToHalfWidth" = { "com.apple.Dictionary - Look Up in Dictionary - doLookupService" = { "com.apple.FolderActionsSetup - Folder Actions Setup - openFilesFromPasteboard" = { "com.apple.Grab - Capture Selection from Screen - variableSelection" = { "com.apple.ImageCaptureService - Import Image - ImportImage" = { "com.apple.QuickTime.service.encodeSelectedAudioFiles - Encode Selected Audio Files - runWorkflowAsService" = { "com.apple.Safari - Add to Reading List - addToReadingList" = { "com.apple.Safari - Search With %WebSearchProvider@ - searchWithWebSearchProvider" = { "com.apple.ScriptEditor2 - Script Editor/Get Result of AppleScript - runAsAppleScript" = { "com.apple.SpotlightService - SEARCH_WITH_SPOTLIGHT - doSearchWithSpotlight" = { "com.apple.Stickies - Make Sticky - makeStickyFromTextService" = { "com.apple.Terminal - New Terminal Tab at Folder - newTerminalAtFolder" = { "com.apple.Terminal - New Terminal at Folder - newTerminalAtFolder" = { "com.apple.Terminal - Open man Page in Terminal - openManPage" = { "com.apple.Terminal - Search man Page Index in Terminal - searchManPages" = { "com.apple.finder - Finder/Open - open" = { "com.apple.finder - Finder/Reveal - reveal" = { "com.apple.finder - Finder/Show Info - showInfo" = { "com.apple.mail - Mail/New Email To Address - mailTo" = { "com.apple.mail - Mail/New Email With Selection - mailSelection" = { "com.apple.services.addToiTunesAsSpokenTrack - Add to iTunes as a Spoken Track - runWorkflowAsService" = { "com.apple.services.encodeSelectedVideoFiles - Encode Selected Video Files - runWorkflowAsService" = { "com.apple.services.setDesktopPicture - Set Desktop Picture - runWorkflowAsService" = { "com.apple.services.showMap - Show Map - runWorkflowAsService" = { "com.apple.systemuiserver - Open URL - openURL" = { "com.evernote.Evernote - ENApplicationServiceMenuItemTitle - serviceCreateNote" = { "com.flexibits.cardhop.mac - Send to Cardhop - sendToCardhop" = { "com.flexibits.fantastical2.mac - Send to Fantastical 2 - sendToFantastical" = { "com.houdah.HoudahSpot4 - New HoudahSpot Search - newSearch" = { "com.houdah.HoudahSpot4 - Search Folders in HoudahSpot - folderSearch" = { "com.houdah.HoudahSpot4 - Search in HoudahSpot - search" = { "com.kapeli.dashdoc - Create Snippet in Dash - createSnippetService" = { "com.kapeli.dashdoc - Look Up in Dash - lookupService" = { "net.pornel.ImageOptim - ImageOptimize - handleServices" = { }
其中每个带引号的字符串代表一项服务。
这是我的问题:
我尝试使用此 sed
命令删除所有无关数据和空格(=
、{
和 }
),但无法成功去掉那个尾随 }
.
b=$(echo $a | sed -E -e 's/ = { / /g' ) && echo "${b}"
即使没有尾随的 }
(无论如何只会在最后一次迭代中产生错误,或者我相信),在我做的这个循环中没有一个字符串被正确解析:
for service in "${b}"; do
defaults write pbs NSServicesStatus -dict-add "${service}" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
"
done
我使用以下命令只是为了测试,并没有得到有效的结果:
/usr/libexec/PlistBuddy -c "Print :NSServicesStatus:${service}" ~/Library/Preferences/pbs.plist
好像只有服务解析正确,不知道是哪个:
Dict {
key_equivalent =
enabled_context_menu = false
enabled_services_menu = false
}
我该如何解决这个问题?
谢谢!
我实际上不容忍使用结构未知工具解析或生成结构化数据,但忽略了这一点 --
while IFS= read -r service; do
service=${service%'"'}; service=${service#'"'}
defaults write pbs NSServicesStatus -dict-add "${service}" '
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
'
done < <(egrep -o '"[^"]+"' <<<"$a")
当我正确理解您的数据后,您可以通过
获得服务
echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p'
您可以使用
回显结构 defaults ...
echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p' |
xargs -I xxx echo 'defaults write pbs NSServicesStatus -dict-add "xxx" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>"
'
当你要调用一个程序defaults
时,第二个echo
可以去掉
echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p' |
xargs -I xxx defaults write pbs NSServicesStatus -dict-add "xxx" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>"
我正在尝试编写一个脚本来遍历 Keyboard Preference Pane
的 Shortcuts > Services
部分中的每项服务并将其禁用。
这是禁用服务的基本命令:
defaults write pbs NSServicesStatus -dict-add SERVICE "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
"
预先获取所有服务并将它们放在脚本中是低效的,因为许多服务是在安装新软件时逐渐添加的。它必须是某种循环。
到目前为止,我一直在尝试使用 defaults
和 awk
来获取包含服务的每一行。
a=$(defaults read pbs NSServicesStatus | awk 'NR%5==2' ) && echo $a
而且,这是输出:
"com.ScooterSoftware.BeyondCompare - Compare Files - bcCompareFiles" = { "com.ScooterSoftware.BeyondCompare - Compare Folders - bcCompareFolders" = { "com.ScooterSoftware.BeyondCompare - Select Left File for Compare - bcSelLeftFile" = { "com.ScooterSoftware.BeyondCompare - Select Left Folder for Compare - bcSelLeftFolder" = { "com.apple.BluetoothFileExchange - Send File To Bluetooth Device - sendFileUsingBluetoothOBEXService" = { "com.apple.ChineseTextConverterService - Convert Text from Simplified to Traditional Chinese - convertTextToTraditionalChinese" = { "com.apple.ChineseTextConverterService - Convert Text from Traditional to Simplified Chinese - convertTextToSimplifiedChinese" = { "com.apple.ChineseTextConverterService - Convert Text to Full Width - convertTextToFullWidth" = { "com.apple.ChineseTextConverterService - Convert Text to Half Width - convertTextToHalfWidth" = { "com.apple.Dictionary - Look Up in Dictionary - doLookupService" = { "com.apple.FolderActionsSetup - Folder Actions Setup - openFilesFromPasteboard" = { "com.apple.Grab - Capture Selection from Screen - variableSelection" = { "com.apple.ImageCaptureService - Import Image - ImportImage" = { "com.apple.QuickTime.service.encodeSelectedAudioFiles - Encode Selected Audio Files - runWorkflowAsService" = { "com.apple.Safari - Add to Reading List - addToReadingList" = { "com.apple.Safari - Search With %WebSearchProvider@ - searchWithWebSearchProvider" = { "com.apple.ScriptEditor2 - Script Editor/Get Result of AppleScript - runAsAppleScript" = { "com.apple.SpotlightService - SEARCH_WITH_SPOTLIGHT - doSearchWithSpotlight" = { "com.apple.Stickies - Make Sticky - makeStickyFromTextService" = { "com.apple.Terminal - New Terminal Tab at Folder - newTerminalAtFolder" = { "com.apple.Terminal - New Terminal at Folder - newTerminalAtFolder" = { "com.apple.Terminal - Open man Page in Terminal - openManPage" = { "com.apple.Terminal - Search man Page Index in Terminal - searchManPages" = { "com.apple.finder - Finder/Open - open" = { "com.apple.finder - Finder/Reveal - reveal" = { "com.apple.finder - Finder/Show Info - showInfo" = { "com.apple.mail - Mail/New Email To Address - mailTo" = { "com.apple.mail - Mail/New Email With Selection - mailSelection" = { "com.apple.services.addToiTunesAsSpokenTrack - Add to iTunes as a Spoken Track - runWorkflowAsService" = { "com.apple.services.encodeSelectedVideoFiles - Encode Selected Video Files - runWorkflowAsService" = { "com.apple.services.setDesktopPicture - Set Desktop Picture - runWorkflowAsService" = { "com.apple.services.showMap - Show Map - runWorkflowAsService" = { "com.apple.systemuiserver - Open URL - openURL" = { "com.evernote.Evernote - ENApplicationServiceMenuItemTitle - serviceCreateNote" = { "com.flexibits.cardhop.mac - Send to Cardhop - sendToCardhop" = { "com.flexibits.fantastical2.mac - Send to Fantastical 2 - sendToFantastical" = { "com.houdah.HoudahSpot4 - New HoudahSpot Search - newSearch" = { "com.houdah.HoudahSpot4 - Search Folders in HoudahSpot - folderSearch" = { "com.houdah.HoudahSpot4 - Search in HoudahSpot - search" = { "com.kapeli.dashdoc - Create Snippet in Dash - createSnippetService" = { "com.kapeli.dashdoc - Look Up in Dash - lookupService" = { "net.pornel.ImageOptim - ImageOptimize - handleServices" = { }
其中每个带引号的字符串代表一项服务。
这是我的问题:
我尝试使用此 sed
命令删除所有无关数据和空格(=
、{
和 }
),但无法成功去掉那个尾随 }
.
b=$(echo $a | sed -E -e 's/ = { / /g' ) && echo "${b}"
即使没有尾随的 }
(无论如何只会在最后一次迭代中产生错误,或者我相信),在我做的这个循环中没有一个字符串被正确解析:
for service in "${b}"; do
defaults write pbs NSServicesStatus -dict-add "${service}" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
"
done
我使用以下命令只是为了测试,并没有得到有效的结果:
/usr/libexec/PlistBuddy -c "Print :NSServicesStatus:${service}" ~/Library/Preferences/pbs.plist
好像只有服务解析正确,不知道是哪个:
Dict {
key_equivalent =
enabled_context_menu = false
enabled_services_menu = false
}
我该如何解决这个问题?
谢谢!
我实际上不容忍使用结构未知工具解析或生成结构化数据,但忽略了这一点 --
while IFS= read -r service; do
service=${service%'"'}; service=${service#'"'}
defaults write pbs NSServicesStatus -dict-add "${service}" '
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>
'
done < <(egrep -o '"[^"]+"' <<<"$a")
当我正确理解您的数据后,您可以通过
获得服务echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p'
您可以使用
回显结构defaults ...
echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p' |
xargs -I xxx echo 'defaults write pbs NSServicesStatus -dict-add "xxx" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>"
'
当你要调用一个程序defaults
时,第二个echo
可以去掉
echo "$b" | tr '{' '\n' | sed -rn 's/[^"]"(.*)".*//p' |
xargs -I xxx defaults write pbs NSServicesStatus -dict-add "xxx" "
<dict>
<key>enabled_context_menu</key><false/>
<key>enabled_services_menu</key><false/>
<key>key_equivalent</key><string>""</string>
</dict>"