使用空字节作为分隔符,将每个参数与参数的位置编号连接起来?

时间:2018-06-04 14:14:03

标签: linux bash

我想用参数的位置编号加入每个参数。我想只使用空字节作为分隔符 以下是我想要的:

printf '%s\x00' "$@" | paste -z -d '\0' <(seq $# | tr '\n' '\0') -

但是我想删除for循环(导致它很难看)并使用管道和/或进程替换。所以问题是:如何使用空字节作为分隔符连接两个空字节分隔的流。 我尝试使用粘贴:

-d'\0'

但是当使用@Service public class ServiceAImpl implements ServiceA { private final String fieldA; @Autowire public ServiceAImpl(@Value("${fieldA}") String fieldA){ this.fieldA = fieldA; } @Override public boolean isFieldA(String text){ return fieldA.equals(text); } } 粘贴调用粘贴时,根本不会插入任何分隔符。如果不指定分隔符,则粘贴使用选项卡。有没有办法可以使用空字节作为列分隔符?还有其他可以在这里使用的实用工具吗?

3 个答案:

答案 0 :(得分:1)

循环不是问题;这是你对循环的使用。

f () {
  local i
  for ((i=1; i<=$#; i++)); do
    printf '%d\0%s\0' "$i" "${!i}"
  done
}

或可能

f () {
  i=1
  for arg; do
    printf '%d\0%s\0' "$((i++))" "$arg"
  done
}

可以在任何POSIX shell中使用,但它会覆盖全局i

答案 1 :(得分:1)

for loop answer by Chepner使用非常简单,绝对可以解决丑陋问题。

正如另一种选择,这是一种无循环的方法:

paste -zd $'\01' <(seq $# | tr '\n' '\0') <(printf '%s\0' "$@") | tr '\1' '\0'

paste命令将两个流粘贴\01作为列分隔符,最后tr命令将\01转换为\0(NUL)字节。

答案 2 :(得分:1)

仅仅为了完整性,一个非循环结构只使用printf(但使用了两次):

printf "$(printf '%d\\000%%s\\000' $(seq $#))" "$@"

内部printf创建一个预先填充序列号的格式字符串。 \000是必要的,以防止插值字符串开头的数字被合并到转义码中。