web-dev-qa-db-ja.com

タブ区切りファイルに値の列を追加する

特定の行数を持つファイルに値の列を追加するにはどうすればよいですか。次のような入力ファイルがあります。

入力ファイル:

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個あるためです。各ファイルを開いて列を貼り付けたくありません。また、ディレクトリに移動して値の列を追加することで、これを自動化する方法があります。値はファイル名から取得され、ファイルの各行の最後/最初の列に追加する必要があります。

18
Ron

次のようなワンライナーループを使用できます。

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///コマンドは二重引用符で囲みます。
23
janos

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

12
yegle

awkを使用できます:

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