根据图案外观编辑文件

根据图案外观编辑文件

我有一个包含文本和数字的文件,如下所示:

state(1, s(1,a), [s(1,b)]).
state(1, s(1,b), [s(1,a)]).
state(1, s(2,a), [s(2,b)]).
state(1, s(2,b), [s(2,a)]).
state(1, s(3,a), [s(3,b)]).
state(1, s(3,b), [s(3,a)]).
state(1, s(4,a), [t(1), t(2)]).
state(1, s(5,a), [t(1), t(3)]).
state(1, s(6,a), [s(6,b)]).
state(1, s(6,b), [s(6,a)]).
...so on

我希望 s(x,y) 中的编号更改如下:

state(1, p(1), 0, [p(2)]).
state(1, p(2), 0, [p(1)]).
state(1, p(3), 0, [p(4)]).
state(1, p(4), 0, [p(3)]).
state(1, p(5), 0, [p(6)]).
state(1, p(6), 0, [p(5)]).
state(1, p(7), -1, [t(1), t(2)]).
state(1, p(8), -1, [t(1), t(3)]).
state(1, p(9), 0, [p(10)]).
state(1, p(10), 0, [p(9)]).
...so on

状态中第三个参数中的 0 和 -1 只是表明存在/存在 ss(或 pp)连接(表示为 0)或不存在(表示为 -1)。

我尝试了“sed”,但我根本没有成功。

我可以获得一些提示或解决方案吗?

答案1

使用正确的文本处理工具而不是 shell 循环:

gawk -F'(,[[:blank:]]+\\[?|\\]\\)\\.)' '!twice{ seen[$2]=NR; next } {
    print $1, "p(" FNR ")", (($3 in seen)?"0, [p("seen[$3]")":"-1, ["$3", "$4)"]).";
}' OFS=', ' infile twice=1 infile

我们将字段分隔符定义为,<one-or-more-whitespaces><with-optional-]>or的集合]).

我们正在处理输入文件infile两次,因此首先我们根据上面设置的 FS 读取第二个字段并将它们添加到关联的seen命名数组中;该数组的键是第二个字段内容,每个值是 NR(NR在 awk 中表示数量输入的记录FNR是相同的,但会为每个下一个输入文件重置);重复此循环,直到所有行读取并完成。变量twice=1和条件!twice用于强制 awk 仅运行第一个块一次,并且第一次我们仅处理输入文件。

该行print用于第二次运行并处理输入文件;我们打印第一个字段,然后p(#)(其中#s 由 FNR 再现);然后我们对照数组中的所有键检查第三个字段seen,如果在数组中找到匹配项,则打印0, [p(#)]).(其中#是在数组中看到匹配键值的位置号),否则打印-1, [...]).

答案2

我们将输入文件称为“sample.txt”

我们首先需要将 0 和 -1 位放入文件中:

cat sample.txt | sed 's/, \[s/, 0, \[s/g' | sed 's/, \[t/, -1, \[t/g' > sample1.txt

一旦我们有了新的“sample1.txt”文件,我们就可以运行以下 bash 脚本 (convert.bash)。

#!/bin/bash

k=0
maxstates=$(wc -l "$1" | gawk '{print $1}')

for i in $(seq 1 "$maxstates")
do
    count=$(grep -c "s($i,a)" "$1")
    if [ "$count" -ne 0 ]
    then
        k=$((k + 1))
        sed -i "s/s($i,a)/p($k)/g" "$1"
    fi
    count=$(grep -c "s($i,b)" "$1")
    if [ "$count" -ne 0 ]
    then
        k=$((k + 1))
        sed -i "s/s($i,b)/p($k)/g" "$1"
    fi
done

现在,运行该文件:

bash convert.bash sample1.txt

它就地编辑了sample1.txt,新内容是:

state(1, p(1), 0, [p(2)]).
state(1, p(2), 0, [p(1)]).
state(1, p(3), 0, [p(4)]).
state(1, p(4), 0, [p(3)]).
state(1, p(5), 0, [p(6)]).
state(1, p(6), 0, [p(5)]).
state(1, p(7), -1, [t(1), t(2)]).
state(1, p(8), -1, [t(1), t(3)]).
state(1, p(9), 0, [p(10)]).
state(1, p(10), 0, [p(9)]).

相关内容