Bash 如何在标签中使用ascii数字数据重新索引文本文件?

Bash 如何在标签中使用ascii数字数据重新索引文本文件?,bash,awk,scripting,Bash,Awk,Scripting,我正在重构代码,并在我的“c”代码中创建了需要重新标记的结构。例: static const unsigned char glyph_065[] = { ... }; static const unsigned char glyph_066[] = { ... }; static const unsigned char glyph_067[] = { ... }; static const unsigned char glyph_065[] = { ... }; stati

我正在重构代码,并在我的“c”代码中创建了需要重新标记的结构。例:

static const unsigned char glyph_065[] = { 
    ... 
};
static const unsigned char glyph_066[] = { ... };
static const unsigned char glyph_067[] = { ... };
static const unsigned char glyph_065[] = { 
   ... 
};
static const unsigned char glyph_066[] = { ... };
static const unsigned char glyph_067[] = { ... };
static const unsigned char glyph_068[] = { ... };
... # then starting at line 300 say
{'A', 38, 20, glyph_065},
{'B', 38, 20, glyph_066},
{'C', 38, 20, glyph_067},
{'A', 38, 20, glyph_065},
{'B', 38, 20, glyph_066},
{'C', 38, 20, glyph_067},
{'D', 38, 20, glyph_068},
...
我想重新编制索引。采取上述措施并使之成为:

static const unsigned char glyph_048[] = { 
  ... 
};
static const unsigned char glyph_049[] = { ... };
static const unsigned char glyph_050[] = { ... };
static const unsigned char glyph_051[] = {
  ... 
};
static const unsigned char glyph_052[] = { ... };
static const unsigned char glyph_053[] = { ... };
static const unsigned char glyph_054[] = { ... };
static const unsigned char glyph_055[] = { ... };
... # then starting at line # 300 say. 
{'0', 38, 20, glyph_048},
{'1', 38, 20, glyph_049},
{'2', 38, 20, glyph_050},
{'3', 38, 20, glyph_051},
{'4', 38, 20, glyph_052},
{'5', 38, 20, glyph_053},
{'6', 38, 20, glyph_054},
...
因此,第一个字段是
glyph_uz
标签中数字的ascii表示形式。我想从一个数字开始,然后数一数。文字字符只是数字的ASCII表示,因此它将在9之后计数为'7','8','9',':',';'


我的脚本知识是BASH,在BASH中这样做是非常可怕的。我确信这可以作为两(2)
awk
1行程序来处理,或者至少与之相近。有人能让我开始吗?

这可以使用静态常量,而不是一行:

$ awk -v s=48 '!f&&/^{/{c=0;f=1} /glyph_/{sub(/\047[^\047]+\047/,sprintf("\047%c\047",s+c)); sub(/glyph_[[:digit:]]+/,"glyph_"s+c); c++} 1' file
static const unsigned char glyph_48[] = {
    ...
};
static const unsigned char glyph_49[] = { ... };
static const unsigned char glyph_50[] = { ... };
static const unsigned char glyph_51[] = {
   ...
};
static const unsigned char glyph_52[] = { ... };
static const unsigned char glyph_53[] = { ... };
static const unsigned char glyph_54[] = { ... };
... # then starting at line 300 say
{'0', 38, 20, glyph_48},
{'1', 38, 20, glyph_49},
{'2', 38, 20, glyph_50},
{'3', 38, 20, glyph_51},
{'4', 38, 20, glyph_52},
{'5', 38, 20, glyph_53},
{'6', 38, 20, glyph_54},
...
num=48
count=0
while read line; do
  if [ $count -lt 300 ]; then
    l=${line/static const unsigned char glyph_.*[]/static const unsigned char glyph_$num[]}
  else
    if [ $count -eq 300 ]; then 
      num=48
    fi
    c=$[ count - 300 ]
    l=${line/[A-Z]/$c}
    l=${l/glyph_*}glyph_$num},
  fi
  echo "$l"
  num=$[ num + 1 ]
  count=$[ count + 1 ]
done <textfile.txt
num=48
计数=0
读行时;做
如果[$count-lt 300];然后
l=${line/static const unsigned char glyph.*[]/static const unsigned char glyph.$num[]}
其他的
如果[$count-等式300];然后
num=48
fi
c=$[计数-300]
l=${line/[A-Z]/$c}
l=${l/glyph_*}glyph_$num},
fi
回音“$l”
num=$[num+1]
计数=$[计数+1]

完成创建一个如下的呆滞脚本:

#!/usr/bin/gawk -f
#

BEGIN { 
        new=NEW_INIT; 
        for (old=OLD_INIT; old<OLD_MAX; old++) {
          oldStr=sprintf("glyph_%03d",old);
          newStr=sprintf("glyph_%03d",new);
          array[oldStr]=newStr; 
          new++ ;
        }
}

{ 
        for (oldStr in array) {
                $0 = gensub(oldStr, array[oldStr], "g", $0);
        }
        print $0
}

因此,您希望将每个
glyph_XX
替换为从
48
(每次+1)开始的内容,并将json字符串中的第一个字段从字母替换为从
0
(每次+1)开始的数字。文字字符“0”只是字形名称
glyph_XXX
中数字
XXX
的ascii表示形式。您应该已经发布了至少10行字形值,因为不清楚您是否希望打印
{:'、38、20、glyph_058}
{10',38、20、glyph_058}
。我在回答中假设了前者。@EdMorton假设我将超过“9”算作“:”,“;”。。。这是正确的。我在问题上补充了这一点。谢谢哦,用
\047
处理单引号的技巧!我努力让它工作。干得好,+1!对于一个长得多的数据集,脚本不会重新开始计算文件的下半部分。不过我想我可以从这里开始。谢谢。脚本不受数据长度的影响。如果它的行为不符合预期,则输入文件中必须有一些特定的值/布局,而这些值/布局在您的问题中没有显示,例如,以
开头的其他行{
或缩进,这与您显示的内容不同。@EdMorton出于某种原因,脚本一直在计算:不值得调试,因为它仍然为我节省了几个小时。谢谢。第一次出现
{
在一行的开头。你必须在输入文件的前面有它。如果你能在输入文件中找到什么键,我可以帮助你编写代码来测试它并重置计数器。
静态常量
定义并不总是在一行。@Jamie更新为使用静态常量而不是在一行上。但是在这种情况下,如何你数了300行吗?请注意,这将删除文件中的所有缩进,并会产生其他副作用,其中一些副作用只会根据输入文件内容和执行它的目录中的文件而变得明显。我还怀疑它会打印
10
,而不是
字形58。Shell是一个n调用工具的环境。操纵文本的UNIX工具是awk。这就是为什么编写健壮的shell代码来操纵文本如此困难的原因。引号不能解决缩进问题,但可以解决字间空间压缩和全局搜索问题。如果在读取时未正确设置IFS,则shell将删除所有的文本从每一行读取并拖尾空白。通过在原始模式下不调用读取(-r)shell将解释反斜杠。除非您有非常特殊的目的,否则您必须始终在IFS=read-r line
时调用read as
,以获得不弄乱正在读取的行的典型预期行为。对于任何计算机上的大文件,awk将大大优于shell脚本。awk通常也会比编译的C代码表现得更好,因为它针对文本操作进行了优化,这超过了解释的开销。
./script.gawk -v OLD_INIT=65 -v OLD_MAX=99 -v NEW_INIT=48 source