Дано такий файл
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
Чи є утиліта командного рядка для переміщення вмісту, щоб результат виглядав так
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Дано такий файл
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
Чи є утиліта командного рядка для переміщення вмісту, щоб результат виглядав так
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Відповіді:
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv
Аналіз CSV не легко виконати лише за допомогою інструментів POSIX, якщо тільки ви не використовуєте спрощений варіант CSV без котирування (щоб коми не з’являлися в полі). Навіть тоді це завдання здається непростим у виконанні програми awk або іншої обробки тексту інструментом. Ви можете використовувати Perl з Text::CSV
, Python з csv
, R з read.csv
, Ruby з CSV ,… (усе це є частиною стандартної бібліотеки відповідної мови, за винятком Perl.)
Наприклад, у 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])
$ apt-get install csvtool
А потім конвертувати
$ csvtool transpose input.csv > ouput.csv
Або в трубопроводі
$ ... | csvtool transpose - | ...
... | csvtranspose | ...
би перемогти це, синтаксис.
Швидке та брудне баш- рішення:
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
клітинка закодована. "this ""is"" example"
Я не переконаний, чи це рішення належним чином обробляє такі випадки
Враховуючи запропоновані обмеження (без цитування, без вбудованих коми), це просто в awk (як це було б в perl, не враховуючи більше тисячі рядків у CSV.pm
, 2300 рядків у csv.rb
- python має всього 450 рядків csv.py
).
Ось приклад для 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];
}
}
До речі: даний приклад мав додатковий простір, який припускав, що ОП буде видалено; інші приклади не стосувалися цієї деталі.
python
, б)ruby
є не менш компактний , ніжpython
та в) це також показує , як передати вхід / вихід файли. Браво @luikore, і ласкаво просимо до Unix & Linux. Будь ласка, тримайтеся навколо.