示例: 文件名: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
,因此这就是printf
和ed
命令所使用的。
答案2
或者,仍然使用ed
, with zsh
,一次调用并且没有命令行限制(参数的长度或数量):
printf 'e %s\n1i\n\t%1$s\n.\nw\nq\n' * | ed
( zsh
'sprintf
支持%m$
说明符以重用参数。)