bash变量使用字符串操作将第一个字母替换为[]中的字母

bash变量使用字符串操作将第一个字母替换为[]中的字母

假设我有:

variable=string

现在想替换第一个字母的括号

${variable/firstletter/[firstletter]}

最后,我想在脚本中使用它来修改正则表达式模式,使其与自身不匹配:

ps -e -o time,user,pid,ppid,comm,args | grep ${variable/firstletter/[firstletter]}

我想用它代替额外的管道和grep -v grep/或pgrep

另外,也许您知道如何使用 awk 实现这样的过程 grep 而不是打印 awk 命令本身?

答案1

您只需要抓住参数的第一个字符,用括号括起来,然后将其余部分添加回去:

bash-[508]$ variable=string
bash-[509]$ echo $variable
string
bash-[510]$ echo $variable to [${variable:0:1}]${variable:1}
string to [s]tring

所以你的命令可能是这样的:

ps -e -i time,user,pid,ppid,comm,args | grep "[${variable:0:1}]${variable:1}"

这是对变量中的字符范围使用 bash 参数替换,给出从哪里开始以及抓取应该多长时间。

${variable:0:1},从字符 0(字符串的开头)开始,并抓取 1 个字符。从而隔离第一个字母,v

${variable:1},然后从字符 1 开始,在没有定义范围的情况下,抓取直到 $variable 末尾的所有内容,抓取ariable.

答案2

我的 .bashrc 中有这样一个函数,但我可以采用多种搜索模式:

psg () {
    local -a patterns=()
    (( $# == 0 )) && set -- $USER
    for arg in "$@"; do
        patterns+=("-e" "[${arg:0:1}]${arg:1}");
    done
    ps -ef | grep --color=auto "${patterns[@]}"
}

是的,我知道pgrep存在。

$ psg fish bash vim grep
glennj       2     1 67 09:00 ?        02:32:31 fish
glennj     153     1  0 09:00 tty2     00:00:06 fish
glennj    3122     1  0 11:08 tty3     00:00:07 fish
glennj    3964   153  0 12:14 tty2     00:00:00 vim supersecretfile
glennj    4992  3122  0 12:41 tty3     00:00:00 bash
glennj    5162  4992  0 12:45 tty3     00:00:00 grep --color=auto -e [f]ish -e [b]ash -e [v]im -e [g]rep

答案3

请尝试:

#!/bin/sh 

variable=rsyslogd

regex="[$(expr "$variable" : '\(.\)')]""${variable#?}"
echo "$regex"
ps -e -o time,user,pid,ppid,comm,args | grep '$regex'

测试:

$ ./script
[r]syslogd
00:00:00 root       521     1 rsyslogd        /usr/sbin/rsyslogd -n

如果变量的第一个字符是特殊的 \ [ ] * ? 这可能会失败ETC。

答案4

也许您知道如何使用 awk 实现这样的过程 grep 而不是打印 awk 命令本身?

使用 GNU awk,我们可以awk通过PROCINFO 获取脚本的 PID 来排除进程本身。

$ pattern=cron
$ ps -e -o time,user,pid,ppid,comm,args  |
  gawk -vpat="$pattern" 'NR == 1 || $3 != PROCINFO["pid"] && $0 ~ pat' 
    TIME USER       PID  PPID COMMAND         COMMAND
00:00:10 root       530     1 cron            /usr/sbin/cron -f

更改$0 ~ patindex($0, pat)以实现固定字符串匹配而不是正则表达式匹配。

当然,您可以pgrep结合使用ps

$ ps -o time,user,pid,ppid,comm,args $(pgrep "$pattern")
    TIME USER       PID  PPID COMMAND         COMMAND
00:00:10 root       530     1 cron            /usr/sbin/cron -f

相关内容