2010-07-18 72 views
7

Tôi có một số tệp mã nguồn có các tab/dấu cách hỗn hợp và tôi muốn chuyển đổi nó thành một tệp nơi nó đã tự động thay thế tất cả các dấu cách bằng tab độ dài không gian tab đã cho (ví dụ: tab ví dụ = 2 khoảng trắng).chuyển đổi tập tin txt chỉ với các tab/không gian hỗn hợp thành các tab (nếu có thể)

Bất kỳ giải pháp dễ dàng nào (với các công cụ Unix phổ biến, MacOSX, bash hoặc zsh)? Một số kịch bản sed hoặc lệnh Python hay như vậy?

Cảm ơn, Albert

+0

Tôi có thể hỏi ai đã bỏ phiếu ở đây không? Và tại sao? Và tại sao không có bình luận? – Albert

+0

Xin lỗi vì đã bỏ phiếu, trước tiên tôi nghĩ rằng điều này sẽ thuộc về superuser.com nhưng sau đó tôi thấy rằng nó không thể được thực hiện mà không cần lập trình. – Philipp

Trả lời

0

Bạn có thể sử dụng một biểu thức chính quy để thay thế N không gian bởi một charater tab. Ví dụ bằng Python:

import re 
re.sub('[ ]{4}', '\t', text) 
+0

Nó không phải là dễ dàng. Điều này ví dụ sẽ không chỉ thay thế không gian được sử dụng cho thụt đầu dòng mà còn ở khắp mọi nơi khác (và nó không nên làm điều đó). – Albert

0

Hai điều,

  1. sed -i là bạn của bạn - sed -i XXX.txt 's/^[ ]\{2\}/\t/g'
  2. Bạn không thể làm cho biểu thức chính quy để nhân sự thay thế tab bằng chiều dài không gian.

Vì AWK-fu của tôi không mạnh (và tôi không biết nếu nó có thể làm những gì # 2 không thể), tôi sẽ viết một tập lệnh PHP để tính toán không gian và thay thế bằng tab.

+0

Ok, ít nhất sẽ chỉ thay thế khoảng trống ngay từ đầu. Mặc dù nó sẽ không thay thế nó nhiều lần. Tôi có lẽ sẽ viết một kịch bản Python mà nó cho tôi. – Albert

0
sed -r 's/ {2}/\t/g' file 
+0

Nó không phải là dễ dàng. Điều này ví dụ sẽ không chỉ thay thế không gian được sử dụng cho thụt đầu dòng mà còn ở khắp mọi nơi khác (và nó không nên làm điều đó). – Albert

1

Tùy thuộc vào ngôn ngữ nguồn, bạn có thể dùng thử GNU indent. Nó có thể làm một số lượng lớn các thứ liên quan đến thụt đầu dòng mã nguồn, mặc dù nó có thể phức tạp hơn bạn cần.

Ví dụ, nếu tôi cung cấp cho các chương trình sau đây để indent -di0 <inputfile>

#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    int i; 
    int j; 
    for (i = 0; i < 10; i++) 
    { 
     for (j = 0; j < 10; j++) 
    { 
     printf("x"); 
    } 
    } 
} 

Nó sẽ thay thế nó bằng:

#include <stdio.h> 

int 
main(int argc, char **argv) 
{ 
    int i; 
    int j; 
    for (i = 0; i < 10; i++) { 
     for (j = 0; j < 10; j++) { 
      printf("x"); 
     } 
    } 
} 

Hoặc, nếu bạn cần một cái gì đó ngu ngốc đơn giản, đó là expand/unexpand lệnh.

+0

'indent' không hoạt động (đó là Python - khó khăn Tôi cũng đang tìm kiếm một giải pháp hoạt động trong các trường hợp khác). 'expand' /' unexpand' quá đơn giản (về cơ bản giống như hầu hết các giải pháp khác được đưa ra ở đây). :) – Albert

+0

Có lẽ tập lệnh reindent.py tại http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py sẽ cung cấp cơ sở cho những gì bạn cần? – mjschultz

+1

Hey, reindent.py trông hầu như giống như những gì tôi muốn. :) Vâng, đã không nhìn nhiều vào nó, không chắc chắn nếu nó chỉ là Python-chỉ (mà có thể đã giúp tôi ngay bây giờ nhưng sẽ không có được giải pháp chung tôi đã tìm kiếm). Mã hóa nó bản thân mình bây giờ ... – Albert

0

Đây là một giải pháp khả thi trong Python:

import re 
import fileinput 

pat = re.compile("^()+") 

for line in fileinput.input(inplace=True): 
    print pat.sub(lambda m: "\t" * (m.end() // 2), line, 1), 
+0

Ok, giải pháp tốt hơn so với những người khác nhưng nó sẽ không hoạt động nếu có không gian hỗn hợp/tab đã có. Sth. như '" \ t \ t "' sẽ trở thành '" \ t "* 3'. – Albert

+0

Nó có hoạt động nếu bạn thay thế regex bằng '"^(| \ t) + "'? Tôi nghĩ rằng tôi không hiểu chính xác yêu cầu. __EDIT: __ đó là * hai * dấu cách trong regex mới, đánh dấu mã nội tuyến không may sụp đổ không gian. – Philipp

0

này sẽ chuyển đổi không gian hàng đầu (thậm chí xen kẽ với các tab) thành các tab. Chỉ định số lượng khoảng trắng cần chuyển đổi bằng cách đặt biến. Không gian đi lạc sẽ bị sụp đổ thành không có gì. Dấu cách và tab xuất hiện sau bất kỳ ký tự nào khác ngoài không gian hoặc tab sẽ không được chạm vào.

tstop=2 
sed "s/^\([[:blank:]]*\)\(.*\)/\1\n\2/;h;s/[^[\n]*//;x;s/\n.*//;s/ \{$tstop\}/X/g;s/ //g;G;s/\n//g" inputfile 

Ví dụ:

[space][space][tab][tab][space][space][space][tab][space]TEXT[space][space][space] 

sẽ được chuyển đổi sang

[tab][tab][tab][tab][tab]TEXT[space][space][space] 

Nếu đó không phải là chính xác những gì bạn đang tìm kiếm, điều chỉnh có thể được thực hiện.

+0

Hoàn toàn không đọc được nhưng trông giống như những gì tôi đang tìm kiếm. :) Btw., Không phải là '... [tab] [dấu cách] TEXT' ở đầu ra? Ít nhất đó là những gì tôi muốn. – Albert

+0

Tôi đang xóa tất cả các khoảng trắng đi lạc. Bạn muốn gì (cho 'tstop = 2')' [tab] [dấu cách] [tab] ... TEXT' trông giống như thế nào? Điều gì về '[tab] [không gian] [không gian] TEXT'? –

+0

'[t] [s] [t] văn bản' sẽ trở thành' [t] [t] văn bản'. '[t] [s] [s] văn bản' sẽ trở thành' [t] [t] văn bản'. '[t] [s] văn bản' phải giữ nguyên. – Albert

Các vấn đề liên quan