在sh

时间:2016-11-23 15:49:49

标签: shell sh

假设我有一个像这样的字符串:

string="1 0 . @ 1 1 ? 2 2 4"

是否可以连接彼此相邻的数字?

string是这样的:10 . @ 11 ? 224

我发现只有基本的东西如何区分整数和其他字符以及如何“连接”它们。但我不知道如何正确迭代。

num=""
 for char in $string; do
    if [  $char -eq $char 2>/dev/null ] ; then
        num=$num$char

4 个答案:

答案 0 :(得分:4)

这是一个几乎纯粹的shell实现 - 将字符串转换为每行一个字符并使用BashFAQ #1 while read循环。

string="1 0 . @ 1 1 ? 2 2 4"
output=''

# replace spaces with newlines for easier handling
string=$(printf '%s\n' "$string" | tr ' ' '\n')

last_was_number=0
printf '%s\n' "$string" | {
  while read -r char; do
    if [ "$char" -eq "$char" ] 2>/dev/null; then # it's a number
      if [ "$last_was_number" -eq "1" ]; then
        output="$output$char"
        last_was_number=1
        continue
      fi
      last_was_number=1
    else
      last_was_number=0
    fi
    output="$output $char"
  done
  printf '%s\n' "$output"
}

答案 1 :(得分:2)

使用更简洁的perl替代方案补充Charles Duffy's helpful, POSIX-compliant sh solution

注意:perl不是POSIX的一部分,但它预装在大多数现代类Unix平台上。

$ printf '%s\n' "1 0 . @ 1 1 ? 2 2 4" | perl -pe 's/\d( \d)+/$& =~ s| ||gr/eg' 
10 . @ 11 ? 224
  • 外部替换s/\d( \d)+/.../eg,全局(g)查找至少2个相邻数字(\d( \d)+)的运行,并用<的结果替换每次运行em>表达式(e)指定为替换字符串(此处表示为...)。

  • 内部替换$& =~ s| ||gr中的表达式,其结果用作替换字符串,从每个相邻数字的运行中删除所有空格:

    • $&表示外部正则表达式匹配的内容 - 相邻数字的运行。
    • =~将对RHS的s调用应用于LHS,即$&(如果没有这个,s调用将隐式应用于整个输入字符串, $_)。
    • s| ||grg的值替换<space>的所有$&个实例,并返回(r)结果,有效删除所有空间。
      • 请注意,|被任意用作s调用的分隔符,以避免与外部使用的惯用/分隔符发生冲突 s来电。

答案 2 :(得分:2)

符合POSIX标准的单行内容:sed:

string="1 0 . @ 1 1 ? 2 2 4"
printf '%s\n' "$string" | sed -e ':b' -e ' s/\([0-9]\) \([0-9]\)/\1\2/g; tb'

它只是迭代地删除两个数字之间的任何空格,直到不再有,导致:

10 . @ 11 ? 224

答案 3 :(得分:0)

这是我的解决方案:

string="1 0 . @ 1 1 ? 2 2 4"
array=(${string/// })
arraylength=${#array[@]}
pattern="[0-9]"
i=0

while true; do
    str=""
    start=$i

    if [ $i -eq $arraylength ]; then
        break;
    fi

    for (( j=$start; j<${arraylength}; j++ )) do
       curr=${array[$j]}
       i=$((i + 1))

       if [[ $curr =~ $pattern ]]; then 
           str="$str$curr"
       else
           break
       fi
   done

   echo $str
done