我在RHEL6下使用bash shell, 我有一个包含三个条目的文本文件..
{text file}
lel
jts
sld
寻找最短的脚本/单行命令来生成单个ssh命令以减少我访问机器的次数
{end result}
ssh id@machine "grep -e lel -e jts -e sld {filename}"
答案 0 :(得分:0)
HELLO PEEPS
执行如下:
FactoryGirl.create(:user, :remote_avatar_url => ...
^
答案 1 :(得分:0)
ssh id@machine egrep '\|lel\|jts\|sld' {filename}
ssh命令行的参数必须被转义,因为get扩展了两次
ssh id@machine egrep "$(readarray -t t<file1; printf "%s" "${t[0]}"; printf -- "\|%s" "${t[@]:1}")" file2
其中file1是您的{text file},file2是远程计算机上的另一个{filename}
答案 2 :(得分:0)
如果远程机器有Gnu grep(甚至可能有其他grep),你可以使用-f -
从stdin一次读取一个正则表达式模式:
ssh id@machine grep -f - {filename} < {patterns.txt}
(请注意,< {patterns.txt}
是您的计算机上ssh
命令的重定向。请不要引用它以将其作为命令的一部分传递。)
构造ssh
远程执行的命令总是有点脆弱,因为ssh
实际上将命令(或命令参数与每个命令之间的单个空格字符连接)作为单个字符串传递给用户在远程计算机上的shell,使用-c
选项。这意味着您需要仔细考虑如何引用参数,以防可能需要。当传递的参数来自其他地方时,这尤其令人讨厌,如你的情况:如果文件的行包含空格或shell元字符,那么你需要安排适当地转义行,以便远程shell将正确解释它们。
Bash的内置printf
实用程序包含%q
格式代码,这对构造此类命令行非常有用。例如,以下内容应安全地引用文件中包含的模式:
ssh id@machine "grep $(
while IFS= read -r; do
printf -- "-e %q " "$REPLY"
done < {patterns.txt}) {filename}"
或者,作为一个可能更具可读性的双线:
mapfile -t patterns < {patterns.txt}
ssh id@machine "grep $(printf -- "-e %q " "${patterns[@]}") {filename}"
答案 3 :(得分:0)
为了给您一些灵活性,您可以使用以下 awk 解决方案,只需生成命令并打印它:
$ awk -v n="id@machine" -v f="filename" '\
{a=((a)?a:"") " -e" $1}END{printf "ssh %s \"grep %s %s\"\n", n, a, f}' text
ssh id@machine "grep -elel -ejts -esld filename"
但是,如果你对实际执行你的ssh感兴趣并抓住输出,那么你需要这样的东西:
$ cat tst.awk
{a=((a)?a:"") " -e" $1} # build up list of "-e ..."
END{
cmd="ssh " n " \"grep " a " " f "\"" # concatenate cmd with vars "n" and "f"
r=((cmd|getline line) > 0 ?line:"") # execute cmd. check for errors.
print r # print result r
close(cmd) # close the cmd
}
你可以这样称呼:
awk -v n="id@machine" -v f="filename" -f tst.awk text
或作为单行:
$ awk -v n="id@machine" -v f="filename" '{a=((a)?a:"") " -e" $1}END{cmd="ssh " n " \"grep " a " " f "\"";r=((cmd|getline line) > 0 ?line:"");print r;close(cmd)}' text
您可以在bash脚本中使用它,循环遍历多个计算机和文件。您唯一需要做的就是用您的resp替换n
和f
变量。 bash vars。