特定の行数を持つファイルに値の列を追加するにはどうすればよいですか。次のような入力ファイルがあります。
入力ファイル:
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個あるためです。各ファイルを開いて列を貼り付けたくありません。また、ディレクトリに移動して値の列を追加することで、これを自動化する方法があります。値はファイル名から取得され、ファイルの各行の最後/最初の列に追加する必要があります。
次のようなワンライナーループを使用できます。
for f in file1 file2 file3; do sed -i "s/$/\t$f/" $f; done
リスト内の各ファイルについて、これはsed
を使用して、各行の終わりにタブとファイル名を追加します。
説明:
-i
フラグをsed
と共に使用して置換を実行し、ファイルを上書きするs/PATTERN/REPLACEMENT/
で置換します。この例では、PATTERNは行の終わりである$
であり、REPLACEMENTは\t
(= a TAB)であり、$f
はループ変数からのファイル名です。シェルが変数を展開できるように、s///
コマンドは二重引用符で囲みます。paste
コマンドがあるときに、これらの強力なツールを推奨する理由を説明します。
$ cat a
A
B
C
D
$ cat b
1
2
3
4
$ paste a b
A 1
B 2
C 3
D 4
少しのトリックで、OPの目的にpaste
を使用できます。ただし、ファイルは置き換えられません。
for f in file1 file2 file3; do
paste $f <(yes $f | head -n $(cat $f | wc -l)) > $f.new
done
これにより、各ファイルの最後の列としてそれぞれのファイル名が新しいファイルに貼り付けられますfilename.new
awk
を使用できます:
awk '{print $0, FILENAME}' file1 file2 file3 ...