如何在 unix shell 中使用长度剪切字符串

how to cut a string using length in unix shell

已编辑

我在查找字符串中的模式时遇到问题。实际上我想比较两个文件并将文件 1 的内容替换为具有以下内容的文件 2

文件 1

000123 moorsevi har NC asee terel
000125 staevil strd NC klass aklsd
000126 carolie asdr NC skdkld kaks
000128 histvil df NC lllas kasd

文件 2

000123 moorsevile har NC asee terel
000125 staevile strd NC klass aklsd
000126 caroline asdr CA skdkld kaks

这里我必须匹配第一列并替换 file2 中的第 2 和 3 列,其中 file2 中行的长度不应更改。

我试过下面的代码。

#! /bin/ksh
IFS=$
ite=0
while read -r line
do
    seqno=$(echo $line|cut -c1-9)
    add=$(echo $line |cut -c10-28)
    state=$(echo $line|cut -c29-31)
    echo "seq no:[$seqno] add:[$add] state:[$state]"
    line1=$(grep $seqno file1)
    add1=$(echo $line1|cut -c10-28)
    state1=$(echo $line1|cut -c29-31)

    echo "on file 1 address:[$add1]: state:[$state1]"

    sed -e "s/$add/$add1/g" -e "s/$state/$state1/g" file2 |tee file2

    ite=`expr $ite + 1`
    echo "iteration= $ite"
done <file2
IFS="\n"
echo "IFS:[$IFS]"

预期输出:

文件 2

000123 moorsevi har NC asee terel
000125 staevil strd NC klass aklsd
000126 carolie asdr NC skdkld kaks

Shell本论坛专家表示使用awk才是正道

向我展示一些使用 awk 实现解决方案的方法。

您只是在分隔文本中提取字段。这是 awk 的标准用例。例如

$ echo "123 moorsevile NC asee terel" | awk '{print ,,}'

123 moorsevile NC

添加相关标签

 ... | awk '{print "seq no:", "add:", "state:"}'

seq no:123 add:moorsevile state:NC

或城市的初始上限

awk '{print "seq no:" ,"add:" toupper(substr(,1,1)) substr(,2), "state:" }'

seq no:123 add:Moorsevile state:NC

或输出中的任意字段定界符

awk -v OFS=" ~ " '{print "seq no:" ,
     "add:" toupper(substr(,1,1)) substr(,2) ,"state:" }'

seq no:123 ~ add:Moorsevile ~ state:NC

很抱歉现在我已经更新了 query.here 我犯的错误是 IFS 设置为 space </code>(<code>while IFS= read -r line) 所以当我用多个 space 加载 line 变量时,它被转换为一个。下面的代码按预期工作。

#! /bin/ksh
IFS=$
ite=0
while read -r line
do
#seqno=$(echo $line|awk '{print substr([=10=],1,6)}')
#add=$(echo $line |awk '{print substr([=10=],7,20)}')
#state=$(echo $line|awk '{print substr([=10=],21,23)}')
#echo "seq no:$seqno add:$add state:$state"
seqno=$(echo $line|cut -c1-6)
add=$(echo $line |cut -c7-20)
state=$(echo $line|cut -c21-23)
echo "seq no:$seqno add:$add state:$state"

ite=`expr $ite + 1`
echo "iteration= $ite"
done <file2
IFS="\n"

我的输出是
seq no:123 add:moorsevile state:NC iteration= 1 seq no:125 add:staevile state:NC iteration= 2 seq no:126 add:caroline state:CA iteration= 3

感谢您的帮助。 如果浪费了您的时间,我深表歉意。

鉴于您的新要求,这就是您想要做的吗:

$ cat tst.awk
BEGIN { FIELDWIDTHS="9 18 11 5" }
NR==FNR { f2[]=; f3[]=; next }
 in f2 { print  f2[] f3[]   }

$ awk -f tst.awk file1 file2
000123   moorsevi har      NC asee    terel
000125   staevil strd      NC klass   aklsd
000126   carolie asdr      NC skdkld  kaks

FIELDWIDTHS 使用 GNU awk。

获取 Arnold Robbins 着的 Effective Awk Programming,第 4 版。