Dado un archivo así
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
¿Existe una utilidad de línea de comandos para transponer el contenido de modo que la salida aparezca así?
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Dado un archivo así
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
¿Existe una utilidad de línea de comandos para transponer el contenido de modo que la salida aparezca así?
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Respuestas:
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv
El análisis CSV no se realiza fácilmente solo con las herramientas POSIX, a menos que esté utilizando una variante CSV simplificada sin comillas (de modo que las comas no puedan aparecer en un campo). Incluso entonces, esta tarea no parece fácil de hacer con awk u otro procesamiento de texto a herramienta. Puede usar Perl con Text::CSV
, Python con csv
, R con read.csv
, Ruby con CSV , ... (Todos estos son parte de la biblioteca estándar del idioma respectivo, excepto Perl).
Por ejemplo, en Python:
import csv, sys
rows = list(csv.reader(sys.stdin))
writer = csv.writer(sys.stdout)
for col in xrange(0, len(rows[0])):
writer.writerow([row[col] for row in rows])
Desde /programming//a/2776078 :
$ apt-get install csvtool
Y luego convertir
$ csvtool transpose input.csv > ouput.csv
O en la tubería
$ ... | csvtool transpose - | ...
... | csvtranspose | ...
superaría eso, en cuanto a sintaxis.
Una solución de bash rápida y sucia :
c=1
file=file.txt
num_lines=$(wc -l < "$file")
for ((i=0; i<num_lines; i++)) {
cut -d, -f$c "$file" | paste -sd ','
((c++))
}
for ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
this "is" example
la célula está codificada "this ""is"" example"
No estoy convencido si se encarga de esta solución tan adecuadamente los casos
Dada la limitación sugerida (sin comillas, sin comas incrustadas), es simple en awk (ya que sería en perl sin tener en cuenta más de mil líneas en CSV.pm
, 2300 líneas en csv.rb
- python tiene solo 450 líneas csv.py
).
Aquí hay un ejemplo para awk:
#!/usr/bin/awk -f
BEGIN { width=0; }
{
max = split($0, list, ",");
# printf "%d:%s\n", NR, $0;
if (width < max)
width = max;
for (n = 1; n <= max; ++n) {
sub("^[ ]*","",list[n]);
sub("[ ]*$","",list[n]);
# printf "\t%d:%s\n", n, list[n];
if ( columns[n] != "" ) {
columns[n] = columns[n] ", ";
}
columns[n] = columns[n] list[n];
}
}
END {
# printf "%d columns\n", width;
for (n = 1; n <= width; ++n) {
printf "%s\n", columns[n];
}
}
Por cierto: el ejemplo dado tenía espacio adicional que OP asumió que sería eliminado; los otros ejemplos no abordaron este detalle.
python
, b)ruby
no es menos portátil quepython
, yc) esto también muestra cómo pasar la entrada / salida archivos. Bravo @luikore, y bienvenidos a Unix y Linux. Por favor, quédate.