如何在 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 版。
已编辑
我在查找字符串中的模式时遇到问题。实际上我想比较两个文件并将文件 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 版。