BASH脚本按位置查找文件中的字符串,匹配,然后修改该位置并插入(如果存在)

BASH脚本按位置查找文件中的字符串,匹配,然后修改该位置并插入(如果存在),bash,shell,sed,sh,ebcdic,Bash,Shell,Sed,Sh,Ebcdic,我在一个文件(input.in)中有几行可能是这样的(星号不是文字;添加星号是为了强调): 我需要能够找到第四个和第五个元素中最后一个字符的值(或者查看位置31和43),以确定实际数字应该是多少,以及它是正数还是负数。修改后的结果应如下所示: 200928,121546,00002,-00000040152,-00000006410,00102020 200928,121546,00002,00000002272,-00000009709,84839923 200928,121546,00003

我在一个文件(input.in)中有几行可能是这样的(星号不是文字;添加星号是为了强调):

我需要能够找到第四个和第五个元素中最后一个字符的值(或者查看位置31和43),以确定实际数字应该是多少,以及它是正数还是负数。修改后的结果应如下所示:

200928,121546,00002,-00000040152,-00000006410,00102020
200928,121546,00002,00000002272,-00000009709,84839923
200928,121546,00003,00000011971,00000002272,93877763
  • {ABCDEFGHI
    对应于所有正极字段,接头为0123456789
  • }JKLMNOPQR
    对应所有负字段和子字段均为0123456789
我可以让所有的正数转换正常工作,但我有问题的负数转换

我的代码看起来有点像这样,用于获取正开关(这是一个“压缩字段”转换btw):

这适用于
{
正的情况,其中sub将为0

其中,
$a
是由a
为in 30 42
do循环引入的。我在识别和更新该字符串的最后一个字符方面没有问题,但我不知道如何在找到相应的字符时只翻转负值。我想看一下整个11组(第4和第5个元素)如果该组中的最后一个字符是
}JKLMNOPQR
,则在第一个位置插入
-
,并将
}JKLMNOPQR
分别替换为
0123456789。
。但是被困在这里了。当然,目标是在SUB完成后使用更改更新文件

代码示例:

    input="input.in"
        for a in 30 42
            do
                while IFS= read -r line
                do
                echo "${line:$a:1} found, converting"
                edbvalue=${line:$a:1}
                case $edbvalue in
                        {)
                        echo -n -e "{ being replaced with 0\n"
                        sed -i -E "s/^(.{$a})\{/\10/" input.in
                        ;;

                        A)
                        echo -n -e "A being replaced with 1\n"
                        sed -i -E "s/^(.{$a})A/\11/" input.in
                        ;;
                        .
                        .
                        .
                        R)
                        echo -n -e "R being replaced with 9\n"
                        sed -i -E "s/^(.{$a})R/\19/" input.in
                        ;;

                        *)
                        echo -n -e "no conversion needed\n"
                        ;;
                esac
                done < "$input"
            done
            
input=“input.in”
30分42秒
做
而IFS=读取-r行
做
echo“${line:$a:1}已找到,正在转换”
edbvalue=${line:$a:1}
案例中的$EDB值
{)
echo-n-e“{正在替换为0\n”
sed-i-E“s/^(.{$a})\{/\10/”input.in
;;
(A)
echo-n-e“A被替换为1\n”
sed-i-E“s/^(.{$a})a/\11/”input.in
;;
.
.
.
(R)
echo-n-e“R被替换为9\n”
sed-i-E“s/^(.{$a})R/\19/”input.in
;;
*)
echo-n-e“无需转换\n”
;;
以撒
完成<“$input”
完成

重复重写输入文件效率极低。您希望一次完成所有替换

sed
一旦你开始做一些不寻常的事情,就很难阅读,所以我建议你改用Awk(如果你想在这方面投入更多的话,可以使用像Python这样的现代脚本语言)

awk-F,'BEGIN{OFS=FS
pos=“{ABCDEFGHI”;neg=“}JKLMNOPQR”;

对于(i=0;我知道了,请编辑您的问题,将样本包装在代码标签中,并让我们知道。这仍然非常不清楚。在定义$a的地方,循环看起来是什么样子?您的意思是在同一输入文件上使用不同的索引循环10次吗?我更新了注释。请让我知道这是否澄清了问题。对不起,首先t post。这里的基础是,我必须检查文件的每一行,检查这些位置,然后根据在列出的位置中标识的每个位置中的内容修改文件。如果检查的列不是顺序的,您的解决方案将如何更改?假设第1、2和5列需要检查,而不是第4和5列?您可以从1 t循环o 5并跳过不想检查的列。如果有大量的列,可以创建一个列索引数组,并循环该数组。
sed -i -E "s/^(.{$a})\{/\10/" input.in
    input="input.in"
        for a in 30 42
            do
                while IFS= read -r line
                do
                echo "${line:$a:1} found, converting"
                edbvalue=${line:$a:1}
                case $edbvalue in
                        {)
                        echo -n -e "{ being replaced with 0\n"
                        sed -i -E "s/^(.{$a})\{/\10/" input.in
                        ;;

                        A)
                        echo -n -e "A being replaced with 1\n"
                        sed -i -E "s/^(.{$a})A/\11/" input.in
                        ;;
                        .
                        .
                        .
                        R)
                        echo -n -e "R being replaced with 9\n"
                        sed -i -E "s/^(.{$a})R/\19/" input.in
                        ;;

                        *)
                        echo -n -e "no conversion needed\n"
                        ;;
                esac
                done < "$input"
            done
            
p["{"] = 0, n["}"] = 0
p["A"] = 1, n["J"] = 1
p["B"] = 2, n["K"] = 2
p["C"] = 3, n["L"] = 3
p["D"] = 4, n["M"] = 4
p["E"] = 5, n["N"] = 5
p["F"] = 6, n["O"] = 6
p["G"] = 7, n["P"] = 7
p["H"] = 8, n["Q"] = 8
p["I"] = 9, n["R"] = 9