Cole arquivos de coluna única com o mesmo nome usando o nome do diretório como nome da coluna

2

Eu tenho vários arquivos de texto com o mesmo nome. Cada arquivo é salvo em uma pasta diferente e cada arquivo contém uma coluna de números, como segue:

FILE.TXT   FILE.TXT   FILE.TXT   FILE.TXT   ....

5            4              5            7
8            2              1            5
6            1              1            1
1            3              5            9
3            1              8            9
.           .                 .          .
.           .                 .          .
.           .                 .          .               

Eu quero mesclar os arquivos em uma planilha (formato CSV) e quero que os nomes das colunas sejam iguais aos nomes das pastas que contêm esse arquivo. Eu tentei loop, da seguinte forma:

#!/bin/bash
  in=a/b/c
  for i in $(cat $in/folders_names.txt); do    # i is the folder name that contain the file.txt
  paste ${in}/${i}/file.txt         
   done > all_files.txt
   sed 's/  */,/g' all_files.txt >all_files.csv &

Este código está colando todas as colunas (de todos os arquivos) em uma coluna (no arquivo all_files.txt). Eu não sei o que estou fazendo errado. Alguma sugestão?

    
por don_crissti 28.09.2015 / 19:37

2 respostas

0
{ paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \n | cut -c2-; \
sed 's|.*|'"${in}"'/&/file.txt|' "${in}"/folders_names.txt \
| tr \n \0 | xargs -0 paste -d,; } > all_files.csv

O primeiro comando

paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \n | cut -c2-

imprime o cabeçalho, por ex. se seu "${in}"/folders_names.txt for:

w
x
y
z

imprime w,x,y,z

O comando sed processa o mesmo arquivo para que cada linha se torne um caminho, por exemplo if in=a/b/c :

a/b/c/w/file.txt
a/b/c/x/file.txt
a/b/c/y/file.txt
a/b/c/z/file.txt

e o resultado é tr formado em uma entrada separada nula alimentada para paste via xargs -0 , então a saída final é, por exemplo,

w,x,y,z
5,4,5,7
8,2,1,5
6,1,1,1
1,3,5,9
3,1,8,9

Se nenhuma linha em folders_names.txt continha espaços em branco (ou seja, nomes de arquivo sane), você poderia executar:

{ paste -d,  /dev/null "${in}"/folders_names.txt | tr -d \n | cut -c2-; \
paste -d, $(sed 's|.*|'"${in}"'/&/file.txt|' "${in}"/folders_names.txt); } > all_files.csv

como o segundo comando seria expandido para

paste -d, a/b/c/w/file.txt a/b/c/x/file.txt a/b/c/y/file.txt a/b/c/z/file.txt
    
por 28.09.2015 / 22:42
0

Outra abordagem. Eu suponho que você pode confiar nos nomes de diretório, nomes de arquivos e conteúdo de folders_names.txt. O uso do comando eval é problemático.

#!/bin/bash

in=a/b/c

build() {
  while read -r i; do
    echo -n "<(echo $i; cat ${in}/${i}/file.txt) "
  done < $in/folders_names.txt
}
eval paste -d "\;" "$(build)" > all_files.csv
    
por 28.09.2015 / 21:45