Учитывая файл, как так
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 | ...
побил бы это, с точки зрения синтаксиса.
Быстрое и грязное решение для bash :
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];
}
}
Кстати: в данном примере было дополнительное пространство, которое, как предполагал OP, будет удалено; другие примеры не касались этой детали.
python
, б)ruby
не менее переносим, чемpython
, и в) это также показывает, как передать ввод / вывод файлы. Браво @luikore, и добро пожаловать в Unix & Linux. Пожалуйста, не торопись.