从文件中读取行并添加到另一个SHELL

时间:2018-03-19 16:48:50

标签: shell sed

我正在尝试解决以下问题: 我有两个文件,一个我希望逐个阅读的congaing行,以及我想在第一次出现模式后添加这些行的其他文件。例如,一个文件包含:

cat
dog
mouse

和其他文件包含

> <Name>
       blabla1


$$$$
> <Name>
       blabla2


$$$$
> <Name>
        blabla3


$$$$

我想这样:

> <Name>
       blabla1
><My_addition>
cat
$$$$
> <Name>
       blabla2
><My_addition>
dog
$$$$
> <Name>
        blabla3
><My_addition>
mouse
$$$$

我现在正在做的是:

filename="test.txt"
while read -r line
do
    a="$line"
    sed -i '0,/$$$$/s//<My_addition>\n'"$fingerprint"'\n\n$$$$/'  my_test.sdf >test_02.sdf
done < "$filename"

但只会更改最后一次出现(鼠标)。我还设法为所有这些添加“鼠标”,但无法弄清楚如何在一个模式发生后添加每一行。

为了更清楚,我试图在文件1中第一个模式出现之前从文件2插入第一行,在文件1中出现第二个模式之前从文件2插入第二行,等等。到目前为止,我得到最后一行在任何模式出现之前,或在最后一次出现之前的最后一行

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

您应该使用真正的解析器,而不是使用sdf ot 解析文件。幸运的是,这里有一个:Perl's Chemistry-Mok

答案 1 :(得分:0)

首先:对于您手头的特定用例,您应该使用真正的解析器。

第二:如果要合并两个文件,请在单独的文件描述符上打开每个文件,并根据需要从每个文件描述符中read;有关while read构造的说明,请参阅BashFAQ #1。没有必要使用sed来完成这项工作。

#!/bin/sh

in1=$1
in2=$2

while IFS= read -r line1 <&3; do : line1="$line1" # debugging
  case $line1 in
    '$$$$')  # when we read a "$$$$" from file 1, write a line from file2 before it
        IFS= read -r line2 <&4 || {
          echo "ERROR: Ran out of lines in $in2 before finishing $in1" >&2
          printf '%s\n' "$line1"; cat <&3; break
        }
        printf '%s\n' '><My_addition>' "$line2" "$line1"
        ;;
    *)
        printf '%s\n' "$line1"
        ;;
  esac
done 3<"$in1" 4<"$in2"

保存为annotate-sdf并运行如下:

cat >test.txt <<'EOF'
cat
dog
mouse
EOF

cat >test.sdf <<'EOF'
> <Name>
       blabla1
$$$$
> <Name>
       blabla2
$$$$
> <Name>
        blabla3
$$$$
EOF

./annotate-sdf test.sdf test.txt

...正如预期的那样输出:

> <Name>
       blabla1
><My_addition>
cat
$$$$
> <Name>
       blabla2
><My_addition>
dog
$$$$
> <Name>
        blabla3
><My_addition>
mouse
$$$$