在已经通过管道输入的命令中引用stdout

时间:2016-03-24 00:57:18

标签: linux bash shell awk grep

我想制作一个简单的dmenu命令来读取命令和名称的文件。然后获取名称并使用dmenu显示它们然后获取dmenu的输出并再次使用该文件运行相关命令。

我到了dmenu显示名字的地步,但我真的不知道从那里去哪里。学习bash对我来说是一项非常艰巨的任务,我真的不知道从哪个看似简单的脚本/命令开始。

这是文件:

Pushbullet
google-chrome-stable --app=https://www.pushbullet.com
Steam
steam
Chrome
google-chrome-stable
Libre Office
libreoffice
Transmission
transmission-qt
Audio Control Panel
sudo pavucontrol & bluberry

这是我迄今为止的命令:

awk 'NR % 2 != 0' /home/rocco/programlist | dmenu | ??(grep -l "stdout" /home/rocco/programlist....)

我的想法是,我可以用应用程序的名称以某种方式管道输入grep或awk,然后获取行号,然后添加一个并将其输入sh。

由于

2 个答案:

答案 0 :(得分:0)

假设您在工作目录中有programlist.txt,您可以使用:

awk 'NR%2 !=0' programlist.txt |dmenu |awk '{system("grep --no-group-separator -A 1 '"'"'"$0"'"'"' programlist.txt");}' |awk '{if(NR==2){system($0);}}'

请注意第一个awk envocation中$0的引用。这对于获取带有空格的名称是必要的,例如" Libre Office"

答案 1 :(得分:0)

我没有使用dmenu的经验,但如果我理解它是如何正常工作的,那么这应该做你想要的。在$(…)中包装命令会将输出作为变量返回,我们可以将其传递给另一个命令。

#!/bin/bash
plist="/home/rocco/programlist"
# pipe every second line to dmenu
selected=$(awk 'NR % 2 != 0' "$plist" | dmenu)
# search for the selected item, get the command after it
cmd=$(grep -A1 "$selected" "$plist" | tail -n 1)
# run the command
$cmd

值得一提的是你的问题。 dmenu发送到stdout或标准输出,但下一行程序将是stdin或标准输入。在任何情况下,grep都无法在标准输入上采用模式,这就是我保存到变量而不是尝试将其传输到某个地方的原因。