Đưa ra một tập tin như vậy
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
Có tiện ích dòng lệnh để hoán đổi nội dung để đầu ra xuất hiện như vậy không
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Đưa ra một tập tin như vậy
First,Last,Age
Cory,Klein,27
John Jacob,Smith,30
Có tiện ích dòng lệnh để hoán đổi nội dung để đầu ra xuất hiện như vậy không
First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
Câu trả lời:
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv
Phân tích cú pháp CSV không dễ dàng thực hiện chỉ với các công cụ POSIX, trừ khi bạn đang sử dụng biến thể CSV được đơn giản hóa mà không có trích dẫn (để dấu phẩy không thể xuất hiện trong một trường). Ngay cả sau đó, nhiệm vụ này dường như không dễ thực hiện với awk hoặc xử lý văn bản khác cho công cụ. Bạn có thể sử dụng Perl với Text::CSV
, Python với csv
, R với read.csv
, Ruby với CSV , MR (Tất cả những thứ này là một phần của thư viện chuẩn của ngôn ngữ tương ứng ngoại trừ Perl.)
Ví dụ: trong 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
Và sau đó chuyển đổi
$ csvtool transpose input.csv > ouput.csv
Hoặc trong đường ống
$ ... | csvtool transpose - | ...
... | csvtranspose | ...
thể đánh bại điều đó, cú pháp khôn ngoan.
Một giải pháp bash nhanh & bẩn :
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
ô được mã hóa "this ""is"" example"
Tôi không tin nếu giải pháp này xử lý đúng các trường hợp như vậy
Với giới hạn được đề xuất (không trích dẫn, không có dấu phẩy nhúng), thật đơn giản trong awk (vì nó sẽ không tính đến hơn một nghìn dòng CSV.pm
, 2300 dòng trong csv.rb
- python chỉ có 450 dòng csv.py
).
Đây là một ví dụ cho 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];
}
}
Nhân tiện: ví dụ đã cho có thêm không gian mà OP giả định sẽ bị xóa; các ví dụ khác không đề cập đến chi tiết này.
python
, b)ruby
không kém phần di động hơnpython
và c) điều này cũng cho thấy cách vượt qua đầu vào / đầu ra các tập tin. Bravo @luikore và chào mừng bạn đến với Unix & Linux. Xin vui lòng dính xung quanh.