首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向数百个文件添加文件名列bash

向数百个文件添加文件名列bash
EN

Stack Overflow用户
提问于 2021-06-18 17:44:57
回答 4查看 639关注 0票数 1

我有数以百计的全基因组关联研究文件,大约一千万行。对于file1.txt

代码语言:javascript
复制
SNP BP B   SE   P
123 12 0.1 0.01 0.1
...

我希望在每个文件的末尾添加一个列,该列只包含该文件的名称,因此file1.txt的最终结果是:

代码语言:javascript
复制
SNP BP B   SE   P   name
123 12 0.1 0.01 0.1 file1.txt
...

我想为数百个文件做这个。目前,我可以使用以下方法添加一列:

代码语言:javascript
复制
for file in *.txt; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done

这将打印整个文件,但不会覆盖现有文件。我只想在已经存在的数据帧中添加一列。任何建议都非常感谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-06-18 17:48:11

代码语言:javascript
复制
tmp=$(mktemp) || { ret="$?"; printf 'Failed to create temp file\n'; exit "$ret"; }
for file in *.txt; do
    awk 'BEGIN{OFS="\t"} {print $0, (FNR>1 ? FILENAME : "name")}' "$file" > "$tmp" &&
    mv -- "$tmp" "$file" || exit
done

如果您有GNU awk,并且没有超过shell参数限制的那么多文件,那么您可以只使用一个调用awk,而不需要周围的shell循环,并显式地创建临时文件(它仍然会在幕后使用临时文件,就像所有可以选择“就地”编辑的工具一样):

代码语言:javascript
复制
awk -i inplace 'BEGIN{OFS="\t"} {print $0, (FNR>1 ? FILENAME : "name")}' *.txt
票数 7
EN

Stack Overflow用户

发布于 2021-06-18 19:52:56

如果ed可用/可接受。

代码语言:javascript
复制
for file in *.txt; do
  printf '%s\n' "2,\$s|^\(.*\)\$|\1 $file|" '1s/$/   name/' 'w' 'q' | ed -s "$file"
done

上面的代码需要使用最后一个字段中的name列手动调整空间。这个文件需要一个临时文件,比如@Ed_Morton所做的和column命令。

代码语言:javascript
复制
tmp=$(mktemp)

for file in *.txt; do
ed -s "$file" <<-EOF
   H
   2,\$s|^\(.\{1,\}\)\$|\1 $file|
   1s/\$/ name/
   w $tmp
   ,d
   0r !column -t $tmp
   w
   Q
EOF
done

警告:ed将把整个文件读入内存。

从OP的样本数据对1400万行进行测试,这一切都是好的,但更多的是错误。(YMMV)

代码语言:javascript
复制
?
Memory  exhausted

感谢@EdMorton指出了内存问题。

票数 0
EN

Stack Overflow用户

发布于 2021-06-18 22:21:02

一种sed

建议的数据文件内容:

代码语言:javascript
复制
SNP BP B   SE   P  
123 12 0.1 0.01 0.1

用不同的文件名复制几个副本

代码语言:javascript
复制
ls  
file1.dat  file2.dat 

cat file*
SNP BP B   SE   P
123 12 0.1 0.01 0.1
SNP BP B   SE   P
123 12 0.1 0.01 0.1

循环遍历dir中的文件;

xargsparallel可以取代for

尽快完成,但如果你有多余的资源的话,就使用更多的资源。

代码语言:javascript
复制
for f in *.dat ; do 
    sed -i "s/\(^SNP.*\)/\1\tname/;s/\(^[0-9].*\)/\1\t$f/g" "$f";
done 

这些文件现在应该有附加的列。

代码语言:javascript
复制
 cat file*
SNP BP B   SE   P   name
123 12 0.1 0.01 0.1 file1.dat
SNP BP B   SE   P   name
123 12 0.1 0.01 0.1 file2.dat
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68039474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档