考虑下面管道分隔文件中的第3列。
A001|akdfjhafa|0000000000034a|hello
B001|bdfaakf|00000008754l|world
B002|sdbvhjsdhg|00000829838{|consider
C003|sdjfhjsdd|00000043724}|bracket
我需要在超量字符转换后将字段转换为十进制值
输出应该是
A001|akdfjhafa|3.41|hello
B001|bdfaakf|-875.43|world
B002|sdbvhjsdhg|82983.80|consider
C003|sdjfhjsdd|-4372.40|bracket
公式很简单
a=1
b=2
c=3
...
h=8
i=9
j=-1
k=-2
...
q=-8
r=-9
{=0
}=-0
示例:
00000043724} = -4372.40
1234k = -123.42
1234p = -123.47
1234e = 123.45
我的想法如下
# replace {,a through 1 using below command.
awk -F"|" '
BEGIN {OFS="|"}
{ gsub("a", "1", $3);
gsub("b", "2", $3);
gsub("c", "3", $3);
gsub("d", "4", $3);
gsub("e", "5", $3);
gsub("f", "6", $3);
gsub("g", "7", $3);
gsub("h", "8", $3);
gsub("i", "9", $3);
gsub("{", "0", $3);
print $0
}' test.dat
但是当j,k,l,m,n,o,p,q,r,}出现时,我用相应的数值替换并打印$ 1,$ 2," - " $ 3,$ 4 。
之后,删除所有前导零。
答案 0 :(得分:2)
这可以在本机bash(不是/ bin / sh,但是bash)中实现,如下所示:
#!/bin/bash
while IFS='|' read -r -a items; do
text=${items[2]}
[[ $text =~ [^1-9][0-9]+$ ]] && text=${BASH_REMATCH[0]} # strip leading 0s
text=${text//a/1} text=${text//b/2} text=${text//c/3}
text=${text//d/4} text=${text//e/5} text=${text//f/6}
text=${text//g/7} text=${text//h/8} text=${text//i/9}
text=${text//j/-1} text=${text//k/-2} text=${text//l/-3}
text=${text//m/-4} text=${text//n/-5} text=${text//o/-6}
text=${text//p/-7} text=${text//q/-8} text=${text//r/-9}
text=${text//"{"/0} text=${text//"}"/-0}
items[2]=$text # write back to array
printf -v output '%s|' "${items[@]}" # put all items in string with pipes after them
printf '%s\n' "${output%'|'}" # strip last pipe, print line with trailing newline
done <test.dat
答案 1 :(得分:0)
我设法编写了一组暂时帮助我的代码。
以下代码将替换&#34; a&#34;通过&#34;我&#34;和&#34; {&#34;具有相应的正值。 gsub(/ ^ 0 * /,&#34;&#34;,$ 3) - 删除前导零。 sed&#39 / s /.. $ /。&amp; /; t; s /^. $ /。0&amp; /&#39; - 在行中最后2个字符前添加小数。
awk -F"|" 'BEGIN {OFS="|"}{gsub("a","1",$3);gsub("b","2",$3);gsub("c","3",$3);gsub("d","4",$3);gsub("e","5",$3);gsub("f","6",$3);gsub("g","7",$3);gsub("h","8",$3);gsub("i","9",$3);gsub(/^0*/,"",$3);print $1,$2,$4,$3}' test.dat| sed 's/..$/.&/;t;s/^.$/.0&/'|sed 's/[{]/0/g' > test1.dat
rm test
以下代码将取代&#34; j&#34;通过&#34; r&#34;和&#34;}&#34;具有相应的负值,并包含一个特殊字符(〜),稍后将用于过滤数据并添加&#39; - &#39;。
awk -F"|" 'BEGIN {OFS="|"}{gsub("j","~1",$4);gsub("k","~2",$4);gsub("l","~3",$4);gsub("m","~4",$4);gsub("n","~5",$4);gsub("o","~6",$4);gsub("p","~7",$4);gsub("q","~8",$4);gsub("r","~9",$4); print}' test1.dat |sed 's/[}]/~0/g'>test2.dat
rm test1
grep -v "~" test2.dat > test3.dat
grep "~" test2.dat|sed 's/~//g'|awk -F"|" '{OFS="|";print $1,$2,$3,"-"$4}' >> test3.dat
rm test2
awk -F"|" '{OFS="|";print $1,$2,$4,$3}' test3.dat >test.dat
rm test3