Thay thế dấu gạch dưới bằng dấu phẩy và xóa dấu ngoặc kép trong CSV


10

Tôi có một tệp CSV là

input.csv

"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
"1_1_0_0_79"
"1_1_0_0_80"
"1_1_0_0_81"
"1_1_0_0_82"
"1_1_0_0_83"
"1_1_0_0_84"
"1_1_0_0_85"

............. và như thế.

Tôi cần chuyển đổi tệp CSV này thành

result.csv 

1,1,0,0,76
1,1,0,0,77
1,1,0,0,78
1,1,0,0,79
1,1,0,0,80
1,1,0,0,81
1,1,0,0,82
1,1,0,0,83
1,1,0,0,84
1,1,0,0,85

Câu trả lời:


24

Cách đơn giản hơn nhiều là sử dụng tr

$ tr '_' ',' < input.csv | tr -d '"'                  
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

Cách thức hoạt động này là trcó hai đối số - tập hợp các ký tự được thay thế và thay thế chúng. Trong trường hợp này, chúng tôi chỉ có bộ 1 ký tự. Chúng tôi chuyển hướng luồng stdin của input.csvđầu vào trthông qua <toán tử shell và chuyển đầu ra kết quả tr -d '"'để xóa dấu ngoặc kép.

Nhưng awkcũng có thể làm được.

$ cat input.csv
"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
$ awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

Cách thức hoạt động này hơi khác một chút: awk đọc từng dòng tệp theo từng dòng, từng tập lệnh nội tuyến /Pattern match/{ codeblock}/Another pattern/{code block for this pattern}. Ở đây chúng ta không có một mẫu, vì vậy nó có nghĩa là thực thi codeblock cho mỗi dòng. gsub()Hàm được sử dụng để thay thế toàn cục trong một dòng, do đó chúng tôi sử dụng nó để thay thế dấu gạch dưới bằng dấu phẩy và dấu ngoặc kép bằng chuỗi null (xóa ký tự một cách hiệu quả). Vị 1trí của mẫu khớp với khối mã bị thiếu, mặc định đơn giản là in dòng; nói cách khác, codeblock gsub()thực hiện công việc và 1in kết quả.

Sử dụng chuyển hướng shell ( >) để gửi đầu ra cho một tệp mới:

 awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv > output.csv

Xin lỗi. Tôi cũng muốn xóa dấu phẩy ngược. Tôi đã cập nhật câu hỏi
RKR

@RKR Trả lời được cập nhật tương ứng, câu trả lời của Ian cũng được cập nhật
Sergiy Kolodyazhnyy

13

Cũng như một cách khác, bạn cũng có thể sử dụng sedlệnh này :

$ sed -e 's/_/,/g' -e 's/"//g' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

1
Trong một trích dẫn, bạn không cần phải thoát một trích dẫn kép.
glenn jackman

Thật vậy @glennjackman! Tôi vừa xóa dấu gạch chéo thoát
IanC

10

Perl, "cưa máy quân đội Thụy Sĩ" xử lý văn bản dòng lệnh, cũng có thể làm điều này. Cú pháp là (không phải ngẫu nhiên) khá giống với trsedví dụ:

perl -pe 'tr/_"/,/d' input.csv > result.csv

hoặc là:

perl -pe 's/_/,/g; s/"//g' input.csv > result.csv

Nhưng thành thật mà nói, nếu bạn không muốn dành thời gian để học một ngôn ngữ lập trình mới (đó thực sự là những gì awk, Perl và sed và các công cụ khác giống như chúng) chỉ dành cho nhiệm vụ cơ bản này, bạn cũng có thể thực hiện nó trong bất kỳ trình soạn thảo văn bản nào hỗ trợ tìm kiếm và thay thế:

  1. Mở tệp CSV trong trình soạn thảo văn bản yêu thích của bạn (chẳng hạn như gedit, kate, mousepad, v.v.; Ngay cả Notepad hoặc Wordpad cũ đơn giản trên Windows cũng có thể làm điều này).

  2. Chọn "Tìm kiếm và thay thế" từ menu (thường được tìm thấy trong "Chỉnh sửa", nếu không có menu "Tìm kiếm" riêng biệt).

  3. Nhập _vào hộp tìm kiếm và ,vào hộp thay thế.

  4. Nhấp vào "Thay thế tất cả".

  5. Lặp lại với "trong hộp tìm kiếm và không có gì trong hộp thay thế.

  6. Lưu các tập tin.

Bây giờ, nếu bạn cần làm điều này cho 100 hoặc 1000 tệp thay vì chỉ một, thì việc học một công cụ dòng lệnh mới bắt đầu có ý nghĩa. Và, tất nhiên, một khi bạn biết cách sử dụng Perl hoặc sed hoặc bất cứ điều gì, thì bạn sẽ tiết kiệm được rất nhiều thời gian và công sức với các nhiệm vụ tương tự sau này. Nhưng đối với chỉ một công việc một lần mà bạn không cần phải làm lại, đôi khi một công cụ tương tác cơ bản như trình soạn thảo văn bản là giải pháp đơn giản nhất.


3

Bạn có thể làm điều này với vimlà tốt.

Mở tệp : vim input.csv, sau đó sử dụng vimcông cụ tìm kiếm nâng cao s. Nhập dấu hai chấm ( :) để vào chế độ lệnh và chạy các lệnh như thế này:

:%s's/_/,/g'  -- Replaces all occurrences of _ with , in the current file.
:s/\"//g -- Replaces all occurrences of " with nothing in the current file.

Khá nhiều lệnh giống như trong câu trả lời của IanC, nhưng bên trong vimthay vì sử dụng sed.


2

Tại sao không chỉ thay đổi giá trị mặc định của giá trị Dấu tách đầu vào và đầu ra

awk -F "_" 'BEGIN { OFS="," }; {gsub(/\"/,""); print $1,$2,$3,$4,$5}' input.csv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.