从bash输出中删除尾部的“,”

从bash输出中删除尾部的“,”,bash,Bash,我有一个解析命令的脚本: while read line; do # The third token is either IP or protocol name with '[' token=`echo $line | awk '{print $3}'` last_char_idx=$((${#token}-1)) last_char=${token:$last_char_idx:1} # Case 1: It is

我有一个解析命令的脚本:

while read line; do
        # The third token is either IP or protocol name with '['
        token=`echo $line | awk '{print $3}'`
        last_char_idx=$((${#token}-1))
        last_char=${token:$last_char_idx:1}
        # Case 1: It is the protocol name
        if [[ "$last_char" = "[" ]]; then
                # This is a protocol. Therefore, port is token 4
                port=`echo $line | awk '{print $4}'`
                # Shave off the last character
                port=${port::-1}
        else
                # token is ip:port. Awk out the port
                port=`echo $token | awk -F: '{print $2}'`
        fi
        PORTS+=("$port")
done < <($COMMAND | egrep "^TCP open")

for p in "${PORTS[@]}"; do
        echo -n "$p, "
done
问题是尾部斜杠

如何使最后一个
端口
在输出中没有尾随的


谢谢

${array[*]}
使用
IFS
中的第一个字符连接元素

IFS=,
echo "${PORTS[*]}"
如果您不想更改IFS,可以改为使用:

printf -v ports_str '%s,' "${PORTS[@]}"
echo "${ports_str%,}"
…或者,从以下内容简化为:


…如果您不想在最后一个端口后添加尾随换行符,请将
echo
更改为
printf“%s'${ports\u str%,}”
。(
echo-n
不推荐;请参阅应用程序用法中的讨论)。

${array[*]}
使用
IFS
中的第一个字符连接元素

IFS=,
echo "${PORTS[*]}"
如果您不想更改IFS,可以改为使用:

printf -v ports_str '%s,' "${PORTS[@]}"
echo "${ports_str%,}"
…或者,从以下内容简化为:

…如果您不想在最后一个端口后添加尾随换行符,请将
echo
更改为
printf“%s'${ports\u str%,}”
。(
echo-n
不建议使用;请参阅的应用程序用法中的讨论)。

为什么不简单:

( for p in "${PORTS[@]}"; do
    echo -n "$p, "
  done ) | sed -e 's/,$//'
为什么不简单地:

( for p in "${PORTS[@]}"; do
    echo -n "$p, "
  done ) | sed -e 's/,$//'
怎么样

$ echo "${ports[@]}" | tr ' ' ','
怎么样

$ echo "${ports[@]}" | tr ' ' ','

不会回答您当前的问题,但如果您将
读取行
更改为
读取f1 f2标记f4
,则效率会更高--如果您让
读取
执行拆分,则不再需要
awk
,然后您可以根据测试从
$f4
$f2
分配
端口。谢谢。你能帮我处理这个请求吗?…另一方面,
$COMMAND |……
有很多问题;请参见描述原因和各种表现更好的备选方案。你也可以考虑使用小写名称来为你自己的变量——所有的CAP名称用于对shell和操作系统的工具有意义的变量,如POSIX @指定的关于<代码> ECHO-N“${SARD[0 ] }”;未设置数组[0];对于“${array[@]}”中的p;do echo-n“,$p”;完成
?@StefanHamcke,这可能是
printf'%s'${array[0]};printf',%s'${array[@]:1}“
;无需任何
echo
s、显式循环,也无需更改数组。这就是说,这是一个很好的方法,如果你不介意的话,我会把它放在我的答案中。它不会回答你眼前的问题,但是如果你把
read line
改为
read f1 f2 token f4
——如果你让
read
进行拆分,就不需要更多的
awk
,然后您可以根据测试从
$f4
$f2
分配
端口。谢谢。你能帮我处理这个请求吗?…另一方面,
$COMMAND |……
有很多问题;请参见描述原因和各种表现更好的备选方案。你也可以考虑使用小写名称来为你自己的变量——所有的CAP名称用于对shell和操作系统的工具有意义的变量,如POSIX @指定的关于<代码> ECHO-N“${SARD[0 ] }”;未设置数组[0];对于“${array[@]}”中的p;do echo-n“,$p”;完成
?@StefanHamcke,这可能是
printf'%s'${array[0]};printf',%s'${array[@]:1}“
;无需任何
echo
s、显式循环,也无需更改数组。也就是说,这是一种很好的方法,如果你不介意的话,我会把它加入我的答案中。这是相当低效的——Paren创建一个子shell(因此
fork()
ing关闭一个新的进程),管道需要另一层子进程创建,然后使用
sed
意味着我们是
fork()
ing另一个子进程,只使用
execve()
syscall将其替换为一个外部程序。我对这个评论有点困惑。亚毫秒的效率是人们一直在寻找的吗?这个解决方案很简单,即使它可能不是最有效的。其他解决方案当然也是值得的。Shell脚本以速度慢著称——在某些方面被描述为太慢,甚至不适合在启动时启动服务的传统角色。它们之所以被视为慢的部分原因是,由于广泛使用极为低效的实践,它们通常比需要的慢几个数量级(字面上说,大约慢100倍)。教授好的实践,无论它们是否立即相关,都意味着更多的人将使用这些实践,因此在实践中可以高效地编写更多的脚本;对于基于Stefan对问题的评论的两种printf配方,100次运行都是0.005s。简单、易于理解和维护也是重要目的。并非所有脚本都需要优化才能达到超高效。在实用程序脚本上获得0.001秒可能并不总是值得的。这是相当低效的——paren创建一个子shell(因此
fork()
关闭一个新进程),管道需要另一层子进程创建,然后使用
sed
意味着我们是
fork()
ing另一个子进程,只使用
execve()
syscall将其替换为一个外部程序。我对这个评论有点困惑。亚毫秒的效率是人们一直在寻找的吗?这个解决方案很简单,即使它可能不是最有效的。其他解决方案当然也是值得的。Shell脚本以速度慢著称——在某些方面被描述为太慢,甚至不适合在启动时启动服务的传统角色。它们之所以被视为慢的部分原因是,由于广泛使用极为低效的实践,它们通常比需要的慢几个数量级(字面上说,大约慢100倍)。教授好的实践,无论它们是否立即相关,都意味着更多的人将使用这些实践,因此更多的脚本将在实践中高效编写