Bash - 改变线和放置' _'在数字之前和之后

时间:2016-05-19 16:35:06

标签: arrays string bash shell cut

我在巴什的第二个问题 - 我有这样的行

New York 17 Hello 1246873 548

我希望得到这个:

New York_17_Hello_1246873_548_

我也可以

Hello_17_New York_123456_54_

*不关心最终下划线是否存在, 但是,我们必须使用数组来解决这个问题,所以我想将它剪切并存储到一个数组中但是卡在中间 任何解决方案?:)

4 个答案:

答案 0 :(得分:1)

在纯粹的bash中,不需要外部工具(sedawk等):

s='New York 17 Hello 1246873 548'

# replace any space immediately before a digit with an underscore
while [[ $s =~ (^|[[:space:]])[[:digit:]] ]]; do
  s=${s//$BASH_REMATCH/_${BASH_REMATCH:1}}
done

# replace any space immediately after a digit with an underscore
while [[ $s =~ [[:digit:]]([[:space:]]|$) ]]; do
  s=${s//$BASH_REMATCH/${BASH_REMATCH:0:1}_}
done

...发射:

New York_17_Hello_12468_73_548_

答案 1 :(得分:1)

一个简单的原生bash解决方案是使用参数扩展:

${variable// /_}

这将 替换variable_的每一次出现。

例如,

test="New York 17 Hello 1246873 548"
echo ${test// /_}

将输出New_York_17_Hello_1246873_548

但是,您请求了基于阵列的解决方案。请注意,这尤其令人费解,因为bash非常适合处理字符串,但对数组而言则不然。

第一步是将文本拆分为单词数组。这可以很容易地完成,因为文本是空格分隔的,空格是参数的默认分隔符:

testArray=($test)
echo ${testArray[0]}

此处的回显将输出New

现在我们需要将其与_一起加入。既然你说你不关心尾随_,你可以打印数组的每个部分,然后是_

for part in ${testArray[@]}; do
    echo -n "${part}_"
done

此处${testArray[@]}会展开数组,然后for可以循环播放,echo -n输出文字而不使用换行符跟随它。我们需要将$part变量括在${...}中,否则bash会将下划线理解为变量名称的一部分。

答案 2 :(得分:0)

您可以使用此sed:

p='New York 17 Hello 1246873 548'
sed -E 's/ *([0-9]+) */_\1_/g; s/_(_[0-9]+)/\1/g' <<< "$p"

New York_17_Hello_1246873_548_

答案 3 :(得分:0)

Perl解决方案:

echo 'New York 17 Hello 1246873 548
Hello 17 New York 123456 54' \
    | perl -lnwe ' @f = split /(?<=[0-9]) | (?=[0-9])/;
                   print join("_", @f), $f[-1] =~ /[0-9]$/ ? "_" : "";
                 '

没有最后的下划线会更容易。