【问题标题】:How to trim, pad and append specific positional data at end of the file using sed in unix如何在 unix 中使用 sed 在文件末尾修剪、填充和附加特定位置数据
【发布时间】:2018-09-06 07:31:41
【问题描述】:

我正在寻找使用 sed 的命令,该命令将选择指定的位置数据,从两端修剪空格,检查长度是否小于 15,然后附加前导 0 使其为 15,并将其附加到行的末尾。

输入:回显“123456 890 2345”

位置:7 到 11

所以数据是“890”

输出:“1234562345000000000000890”

【问题讨论】:

  • 这可能有助于 bash 的部分工作。 s=7; e=11; x="123456 890 2345"; echo ${x:$s-1:$e-$s+1}

标签: shell unix sed scripting trim


【解决方案1】:

通过标记您的问题sh(意味着 POSIX shell 兼容),您在一定程度上限制了可以使用的高级 shell 功能(例如 sting 索引等)。 sed 是一个很棒的流编辑器,有很好的行范围选择能力,但在字符索引选择能力方面受到限制。 awkawk '{print substr...}' 的另一种选择,它可以毫无问题地处理这项工作。

POSIX shell 也可以使用传统的expr ... 子字符串、长度和索引工具来完成这项工作,使用字符类来删除空格。鉴于您标记了您的问题sh,让我们看一下处理子字符串提取、替换为空格和附加零填充的 15 字符表示的子字符串的方法。

下面的脚本是注释很好的内联,但本质上是获取输入的长度,用于提取子字符串的位置的索引(注意 POSIX shell 索引来自1 而不是0),构建一串空格替换提取的子字符串,从子字符串中修剪前导/尾随空格,然后将它们全部放回一起,使用printf将修剪后的子字符串视为整数,将零填充15-character宽子字符串附加到末尾,例如

#!/bin/sh

str="123456 890 2345"   # input
s=7                     # start positon
e=11                    # end position
spc=                    # spaces string (unset)
i=0                     # counter

strlen=$(expr length "$str")                    # input length
sub=$(expr substr "$str" "$s" "$((e - s + 1))") # extract ' 890 '
slen=$(expr length "$sub")                      # length sub

while [ "$i" -lt "$slen" ]  # build spaces replacement
do
    spc="$spc "
    ((i++))
done

# get non-space start index in sub to trim leading spaces
# (adjust character class as required)
sidx=$(expr index "$sub" "[0123456789]")

# if start index > 1 extract substring beginning at sidx
((sidx > 1)) && sub=$(expr substr "$sub" "$sidx" $((slen - sidx + 1)))

# get index of any space at end
eidx=$(expr index "$sub" "[ ]")

# if end index > 1 extract substring up to eidx
((eidx > 1)) && sub=$(expr substr "$sub" "1" $((eidx - 1)))

# build result string
res="$(expr substr "$str" "1" $((s - 1)))"  # first s-1 chars in str
res="$res$spc"                              # append spaces
# append final characters after e in str
res="$res$(expr substr "$str" $((e + 1)) $((strlen - e)))"
res="$res$(printf "%015d" "$sub")"  # use printf to format 0-padded sub
# (note, if not decimal, use loop to append zeros)

echo "input : '$str'"
echo "result: '$res'"  # output final result

使用/输出示例

$ sh substrapp.sh
input : '123456 890 2345'
result: '123456     2345000000000000890'

检查一下,如果您有任何问题,请告诉我。

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -r 's/./&\n/11;T;s//\n&/7;s/(\n\s*(\S+)\s*\n.*)/\1\n\2/;:a;ta;s/^([^\n]*\n *)[^ \n]/\1 /;ta;s/\n//;s///;:b;tb;/\n.{15}$/s/\n//;t;s/\n/&0/;bb' file
    

    在第 11 个字符后添加换行符。如果替换成功则继续,否则打印当前行并且不对该行进行进一步处理。在第 7 个字符前加上换行符。使用替换和反向引用,添加一个换行符,后跟从字符 7 到字符 11 的原始行的子字符串的空格剪切部分。使用循环将原始子字符串替换为空格,然后删除换行符。使用循环将0's 添加到附加的空格剪切子字符串中,以使新字符串的总长度为 15 个字符。最后删除换行符并打印结果字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-10
      • 2011-11-21
      相关资源
      最近更新 更多