【问题标题】:Change string in multiple files using sed使用 sed 更改多个文件中的字符串
【发布时间】:2017-09-06 21:34:16
【问题描述】:

我有多个这样的文件:

67 572 Cy_aJATC23 ?????????????????????????GCCCTGCTGAGGCCCATAGTCACAGAAGGACAAAGTGCCAGACCACCCCCTTTCTGGCCTTTAATCTGTGGTGGTGCTGGCACTGCCTCCACACGGGCCTCACTGTGTGACAATGCTCCTTTCAGGTGAGGTCTGATCGGGACAAGTTCACAATCATGCTGGATGTAAAACACTTCTCTCCCGAAGACTTGAGTGTGAAGATTATTGATGACTTTGTGGAAATCCATGGCAAGCACAGTGAAAGGCAGGTAAGTGGAAGTGATGGTGATGGTGGAGAAACTGGAGAGTCCAGCTCCGTTTCCCTTCTTTCCAACGGTTCTCAGCTGAAGGAAAAAAAAAAAGAATATATCAGAAGAAGGAGTTAATTATGAATTGTCATTATTGGCACGGCCTGTTCCCATAGAGCCCCCATCTGATATCTGACAATAACAA

我想改变第一行

65572

['文件名'572]

文件的名称是“ACA_exon2.phylip-sequential”,我只想要第一部分“ACA_exon2”,但我没问题,我可以在之后更改它。

我很接近这个

for file in ~/folder/*; do sed -E 's/^ (\w+)( \w+)/\[$file\2]/g' $file ; done;

这是结果

[$文件 572] Cy_aJATC23 ??????????????????????????????????????????????????? ????????????????TACCACCCAAGATGTTAACAAGCTGGCATGTTTTGAGCATCAAAGATAGAGAGGAAACTGTGTTTACATGTTTGGCACAAAAACTAATGAGGAAAGTCAATTGGCCCTTTGTCTTGAGGGTCTGAAGAGCCGCGCTCTAATGTTTGGTTTCTTGGTTGGCACTTGTTCAAGTAATCACTCGTGGCCTGACAAAGCAGCACTTGTGTTTTATTAGTGGCCATGCTGAACTCTCCTGCCTGGGCTATGTTGCCTCTCAATAGAGCACTGCACCAGAGGGCATACTTATTTGAAAACACTAAATCAGAGCATGATGATCTTTGCCCGACAAATACAACCAAGAGAGGAGAAAGAAAAGTGACAACAGCTCTCCTTTTGTTAGAGAAAGTGAGGAAACAACAACTGGTGTGTGTGCATGTGCATGTGTGTAAGATGAGTCCTGAAACACCGGTGACGAAATGAGCAAAACTTTGTTCCCATAATGTGATGCTCAGAACCAACTGGATT???

sed 无法将 $file 识别为将名称保留在文本中的命令...

我想要这个

[ACA_exon2 572] Cy_aJATC23 ??????????????????????????????????????????????????? ????????????????TACCACCCAAGATGTTAACAAGCTGGCATGTTTTGAGCATCAAAGATAGAGAGGAAACTGTGTTTACATGTTTGGCACAAAAACTAATGAGGAAAGTCAATTGGCCCTTTGTCTTGAGGGTCTGAAGAGCCGCGCTCTAATGTTTGGTTTCTTGGTTGGCACTTGTTCAAGTAATCACTCGTGGCCTGACAAAGCAGCACTTGTGTTTTATTAGTGGCCATGCTGAACTCTCCTGCCTGGGCTATGTTGCCTCTCAATAGAGCACTGCACCAGAGGGCATACTTATTTGAAAACACTAAATCAGAGCATGATGATCTTTGCCCGACAAATACAACCAAGAGAGGAGAAAGAAAAGTGACAACAGCTCTCCTTTTGTTAGAGAAAGTGAGGAAACAACAACTGGTGTGTGTGCATGTGCATGTGTGTAAGATGAGTCCTGAAACACCGGTGACGAAATGAGCAAAACTTTGTTCCCATAATGTGATGCTCAGAACCAACTGGATT???

你能帮帮我吗?

提前致谢

【问题讨论】:

  • 这会方式awk中更容易做到
  • 请务必在 Bash btw 中的变量扩展周围使用引号。 "$file" 在你上面的例子中......
  • 它不适用于"$file" - ["$file" 572]
  • 我可以看到它不起作用。只是指出变量需要在 Bash 中引用,否则可能会发生不好的事情。请参阅我的答案以了解引用的内容和未引用的内容。

标签: string bash sed filenames


【解决方案1】:

给定:

$ cat f1.exon
67 572 Cy_aJATC23 ?????????????????????????
GCCCTGCTGAGGCCCATAGTCACAGAAGGACAAAGTGCCAGACCACCCCCTTTCTGGCCTT
$ cat f2.exon
67 573 Cy_aJATC23 ?????????????????????????
GCCCTGCTGAGGCCCATAGTCACAGAAGGACAAAGTGCCAGACCACCCCCTTTCTGGCCTT

你可以在awk

$ awk 'FNR==1{$1="[" FILENAME; $2=$2 "]"} 1' *.exon
[f1.exon 572] Cy_aJATC23 ?????????????????????????
GCCCTGCTGAGGCCCATAGTCACAGAAGGACAAAGTGCCAGACCACCCCCTTTCTGGCCTT
[f2.exon 573] Cy_aJATC23 ?????????????????????????
GCCCTGCTGAGGCCCATAGTCACAGAAGGACAAAGTGCCAGACCACCCCCTTTCTGGCCTT

sed 中的相同概念:

for fn in *.exon; do 
    sed -E '1s/^[[:digit:]]+( [[:digit:]]+)/['"$fn"'\1]/' "$fn"
done    
# same output

如何将其保存在文件中?

您可以将文件重定向到临时文件,然后mv 临时文件将原始文件重命名为新内容:

for fn in *.exon; do 
    awk 'FNR==1{$1="[" FILENAME; $2=$2 "]"} 1' "$fn" > a_temp_exon
    mv a_temp_exon "$fn"
done

对于sed,只需使用-i 就地替换选项。

解释:

awk 'FNR==1{$1="[" FILENAME; $2=$2 "]"} 1' *.exon
      ^   ^                                       first line only
           ^                          ^           do this action
            ^                                     first field
               ^     ^                            literal [ and FILENAME
                             ^                    second field
                                 ^                it's same value
                                    ^             literal ]
                                        ^         print the line

【讨论】:

  • 很好,它工作正常。如何将其保存在文件中?另外,你知道如何只保留 f1 和 f2 (你的例子)吗?另外,请您解释一下您的命令吗?
  • 另外,你知道如何只保留 f1 和 f2(你的例子)吗?我不明白你的那部分问题......
  • 谢谢@dawg!而不是f1.exon,只是f1
  • 这只是因为我使用的演示文件名。如果您在f1 中的实际文件名将被使用。如果您的实际文件名是 f1.ext 并且您只想插入 f1 您可以使用 bash 参数扩展或正则表达式来删除它。
  • 好的,谢谢,我只是想知道我是否可以按照您提供的命令执行此操作。但是很完美! ;)
【解决方案2】:

您尝试使用单引号,因此其中的变量不会被扩展。 试试这个:

sed -E "s/^ (\w+)( \w+)/\[$file\2]/g" $file

sed -E 's/^ (\w+)( \w+)/\['$file'\2]/g' $file

【讨论】:

  • 不,sed 不接受:'sed: $ for file in ~/folder/*;做 sed -E "s/^ (\w+)( \w+)/[$file\2]/g" $file ;完毕; sed: -e 表达式 #1, char 22: `s' 的未知选项
  • 不,同样的错误,双倍打印 ["$file" 572]
  • 你能告诉我你是如何使用双引号的吗?我的意思是得到 ["$file" 572]
  • for file in ~/folder/*; do sed -E 's/^ (\w+)( \w+)/\["$file"\2]/g' $file ; done;
  • 这种情况下还是使用外单引号,变量不会被展开
【解决方案3】:

Maxim 关于变量扩展是正确的,但是我相信您在使用双引号时需要转义反斜杠:

sed -E "s/^ (\\w+)( \\w+)/\\[$file\\2]/g" $file

【讨论】:

  • @luke,你是对的,当我们对整个字符串使用双引号时,我们需要双斜杠
猜你喜欢
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
  • 2016-09-09
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多