如何插入文件名作为文件头?

如何插入文件名作为文件头?

示例: 文件名:ENSG00000000003

ENSG00000000003 43120.829491094
ENSG00000000005 39604.4956791524
ENSG00000000419 7645.05624570546
ENSG00000000457 2157.49855156382
ENSG00000000460 3317.98417717746
ENSG00000000938 6327.40515535397

预期产出;理想情况下,文件名前面有一个制表符:

    ENSG00000000003
ENSG00000000003 43120.829491094
ENSG00000000005 39604.4956791524
ENSG00000000419 7645.05624570546
ENSG00000000457 2157.49855156382
ENSG00000000460 3317.98417717746
ENSG00000000938 6327.40515535397

我想对我的 45000 个文件一起循环执行此操作

答案1

我将使用标准 UNIX 编辑器(当然!):

for f in ENSG*
do
  printf '1i\n\t%s\n.\nw\nq\n' "$f" | ed -s "$f"
done

这会向 发送一个小命令脚本ed,即:

  • 在第 1 行,插入 ( i) 一些文本;文本printf作为文件名传递,前面带有制表符 ( \t)
  • 插入文本 ( .) 后,将文件保存到磁盘 ( w) 并退出 ( q)

如果确实文件数量超出了命令行限制,那么您可以使用命令find;根据需要调整参数(起始目录、文件名等):

find . -name 'ENSG*' -exec sh -c 'printf "1i\n\t%s\\n.\nw\nq\n" "$1" | ed -s "$1" ' findsh {} \;

核心解决方案是相同的,但包含在我所说的“查找外壳”中——针对每个匹配的(单个)文件名find执行;sh -c ...findsh字符串是一个存根名称$0,文件名将代替大括号传递到该 shell {}。然后 shell 本身将文件名作为参数$1,因此这就是printfed命令所使用的。

答案2

或者,仍然使用ed, with zsh,一次调用并且没有命令行限制(参数的长度或数量):

printf 'e %s\n1i\n\t%1$s\n.\nw\nq\n' * | ed

( zsh'sprintf支持%m$说明符以重用参数。)

相关内容