在制表符分隔的文件中添加一列值

Ron*_*Ron 18 linux awk shell-script

如何在具有特定行数的文件中添加一列值。我有一个这样的输入文件:

输入文件:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248
Run Code Online (Sandbox Code Playgroud)

输出文件:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我想添加一列值,最多为文件中的行数。值保持一致,例如“file1”。

原因是我有 100 个这样的文件。我不想打开每个文件并粘贴一列。还有什么方法可以通过进入目录并添加一列值来自动执行此操作。该值来自文件名,必须在文件的每一行的最后/第一列中添加该文件名。

jan*_*nos 27

您可以使用这样的单行循环:

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done
Run Code Online (Sandbox Code Playgroud)

对于列表中的每个文件,这将用于sed在每行的末尾附加一个制表符和文件名。

解释:

  • 使用-i标志 withsed执行就地替换,覆盖文件
  • 执行替换s/PATTERN/REPLACEMENT/。在这个例子中,PATTERN 是$行尾,REPLACEMENT 是\t(= 一个制表符),并且$f是来自循环变量的文件名。该s///命令在双引号内,以便 shell 可以扩展变量。


yeg*_*gle 14

来吧,为什么你们在有paste命令的时候推荐那些强大的工具!

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4
Run Code Online (Sandbox Code Playgroud)

稍加技巧,您就可以paste用于 OP 的目的。但是,它不会替换就地文件:

for f in file1 file2 file3; do 
    paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done
Run Code Online (Sandbox Code Playgroud)

这会将相应的文件名作为每个文件的最后一列粘贴到新文件中 filename.new


cuo*_*glm 13

您可以使用awk:

awk '{print $0, FILENAME}' file1 file2 file3 ...
Run Code Online (Sandbox Code Playgroud)