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


17

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

输入文件:

SPATA17 1   217947738
LYPLAL1 1   219383905
FAM47E  4   77192838
SHROOM3 4   77660162
SHROOM3 4   77660731
SHROOM3 4   77662248

输出文件:

SPATA17 1   217947738 file1
LYPLAL1 1   219383905 file1
FAM47E  4   77192838  file1
SHROOM3 4   77660162  file1
SHROOM3 4   77660731  file1
SHROOM3 4   77662248  file1

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

原因是我有100个这些文件,我不想打开每个文件并粘贴一列。也可以通过进入目录并添加一列值来实现此目的的自动化。该值来自文件名,该文件名必须添加到文件的最后/第一列的每一行中。

Answers:


22

您可以像这样使用单线循环:

for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done

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

说明:

  • 使用-i标志和sed进行就地替换,覆盖文件
  • 用进行替换s/PATTERN/REPLACEMENT/。在此示例中,PATTERN是$,行的结尾,REPLACEMENT是\t(= TAB),并且$f是循环变量中的文件名。该s///命令在双引号内,以便外壳程序可以扩展变量。

代码有效。您能否解释引号中的内容?
罗恩

就像在处理列时使用“ awk”一样,“ sed”也用于类似情况。我是“ awk”和“ sed”的新手。
罗恩

@Ron sed对于模式替换和就地保存最为实用。对于您保存文件的要求,这是一个相对方便的选择。如果您不需要写回正在处理的同一文件,则awk通常更容易使用。
janos 2014年

就个人而言,我awk经常被的输入/输出字段分隔符绊倒,因此请尽量避免使用它,以使其sed更具吸引力。
user5359531 2016年

11

来吧,为什么你们在有paste命令的情况下推荐那些功能强大的工具!

$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A   1
B   2
C   3
D   4

稍作花招,您就可以使用pasteOP的目的。但是,它不会就地替换文件:

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

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


谢谢!paste当然是隐藏的宝石。
neu242

10

您可以使用awk

awk '{print $0, FILENAME}' file1 file2 file3 ...

由于每个文件都有不同的名称,所以我必须做100次。有没有办法做一次?
罗恩

否,FILENAME是中的变量awk,它扩展为awk正在处理的当前文件名。您只需完成一项操作,即可将所有文件输入awk
cuonglm

好的,但是如何将输出定向到每个文件的新文件中?awk在处理时是否存储每个文件?
罗恩

如果您拥有GNU awk 4.1.0或更高版本,则可以使用-i就地编辑。否则,您应该将awk输出重定向到临时文件,然后用于grep从每个文件中提取行。
cuonglm

好吧,您可以做for file in *; do awk 'BEGIN{OFS="\t"}{print $0, FILENAME}' $file; done
fedorqui 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.