gpt4 book ai didi

bash - 从引用列表中替换文件中的字符串

转载 作者:行者123 更新时间:2023-12-02 21:03:38 24 4
gpt4 key购买 nike

有一些线程似乎在问与我感兴趣的相同的问题,但有些答案似乎很难概括(或者我不够聪明)。例如

how to replace strings in file based on values from another file? (example inside)

Replacing strings in file, using patterns from another file

我有一些复杂的文件,如下所示:

 ((PLT_01736:0.06834090301258281819,(((PLT_01758:0.04822932915066913823,PLT_01716:0.08160284537473952438)98:0.04771898687201567291,((PAU_02074:0.04683560272944583408,PAK_01896:0.02826787310445108212)95:0.03010698277052889504,PLT_02424:0.06991513512243620332)99:0.06172493035971356873)90:0.05291396820697712167,((PAK_02014:0.00000187538096058579,PAU_02206:0.00721521619460035492)100:0.43252725913741080221,((PLT_02568:0.06262043352060168988,(PAU_01961:0.02293694470289835488,PAK_01787:0.01049771144617094552)98:0.05833869619359682152)100:0.65266156617675985530,(PAK_03203:0.06403695571262699171,PAU_03392:0.03453883849938884504)99:0.10276841868475847241)2:0.14443958710162313475)10:0.20176450294539299835)9:0.01245548664398392694)92:0.05176685581730120639,(PAK_02606:0.03709141633854080161,PAU_02775:0.01796540370573110335)57:0.01492069367348663675,PLT_01696:0.01562657531699716829);

(这些是 Newick 格式的系统发育树,以防有人感兴趣)

我需要更改此文件中的所有 ID 键(看起来像 XXX_YYYYY 的位),但不确定最好的方法是什么。

它们需要被它们所属的“组”(操纵子)替换,所以我认为制作某种索引文件是可行的方法,例如,PLT_01696 被替换为 group_1 说:

key 文件:

PLT_01696 group_1
PLT_01736 group_1
PLT_01758 group_1
....
PAU_02074 group_2

所以我想如果我可以将文件传递给 sed 或类似的文件,让它读取并查找第一列中的条目,并将其替换为我在其中配对的任何内容第 2 列是执行此操作的最佳方法吗?该文件最终将包含大约 350 个单独的键,最终将被分为大约 12 个组。

文件最终看起来像:

((group_1:0.06834090301258281819,(((group_1:0.04822932915066913823,group_1:0.08160284537473952438)98:0.04771898687201567291,.....

我愿意接受其他建议,这对我来说似乎是最明显的。这是在 Ubuntu 14.04 上,所以任何解决方案都是公平的游戏,但我更喜欢 bash(和一点 Perl)。

最佳答案

这种情况下的一个解决方案是编写一个 sed 脚本,该脚本写入您要执行的 sed 脚本。看来操纵子前面是 (, 并且总是后面是 :。因此,假设您的文件包含以下映射:

PLT_01736 group_1

然后为该文件中的每一行创建一个 sed 操作,如下所示:

s/\([,(]\)PLT_01736:/\1group_1:/g

其中 g 可能不是必需的(我不知道给定的操纵子是否可以在一行中出现多次)。初始字符类捕获 (, 以及 \(\) 记住这一点,然后是通过特定的 ID 键和冒号;替换操作输出记住的字符、替换文本和冒号。跟踪前面和后面的字符的优点是,如果由于某种意外,您有操纵子 PLT_00100 和 PLT_001001(其中一个操纵子是另一个的前缀),跟踪周围的字符可以确保正确的匹配。否则,您必须确保最长的匹配首先出现在脚本中,这比较麻烦(sort -r 可能会排序出来,但是……)。

因此,假设映射位于文件 mapping.data 中,您可以使用:

sed 's%\([A-Z]*_[0-9]*\)  *\(.*\)%s/\\([,(]\\)\1:/\\1\2:/g%' mapping.data > script.sed
sed -f script.sed newick.phylogenetic.tree.data > transformed.data

这在生成s%%%操作中使用了%,输出s///(需要小心)。 s%%% 的搜索部分查找零个或多个大写字母、下划线以及零个或多个数字,并使用 \(\);后跟一个或多个空格,再后跟一些也被捕获的其他字符。如果 ID 键可以具有不同的结构,则适当更改匹配的正则表达式。我假设输入数据是“干净的”,因此无需担心仅处理包含三个字母、下划线和五个数字的行,并且没有尾随空格。将两个部分( key ID 和替换)隔离后,只需生成输出 s/// 命令,记住将输出中必须出现的反斜杠加倍。

根据您的输入数据和键列表,我得到的输出是:

((group_1:0.06834090301258281819,(((group_1:0.04822932915066913823,PLT_01716:0.08160284537473952438)98:0.04771898687201567291,((group_2:0.04683560272944583408,PAK_01896:0.02826787310445108212)95:0.03010698277052889504,PLT_02424:0.06991513512243620332)99:0.06172493035971356873)90:0.05291396820697712167,((PAK_02014:0.00000187538096058579,PAU_02206:0.00721521619460035492)100:0.43252725913741080221,((PLT_02568:0.06262043352060168988,(PAU_01961:0.02293694470289835488,PAK_01787:0.01049771144617094552)98:0.05833869619359682152)100:0.65266156617675985530,(PAK_03203:0.06403695571262699171,PAU_03392:0.03453883849938884504)99:0.10276841868475847241)2:0.14443958710162313475)10:0.20176450294539299835)9:0.01245548664398392694)92:0.05176685581730120639,(PAK_02606:0.03709141633854080161,PAU_02775:0.01796540370573110335)57:0.01492069367348663675,group_1:0.01562657531699716829);

关于bash - 从引用列表中替换文件中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37117060/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com