Cách thay thế nhiều khoảng trắng bằng một tab


27

Tôi có một số tệp văn bản chứa một số cột được phân tách bằng nhiều khoảng trắng khác nhau, nhưng thay vào đó tôi cần một tab duy nhất làm dấu phân cách. Có thể làm trong Bash?


Cảm ơn cho đầu vào tuyệt vời, nhưng tôi có một số khoảng trắng bên trong một cột, vì vậy tôi phải tránh đánh dấu một khoảng trống. xin lỗi vì điều đó
user_unknown

Câu trả lời:


31

Để chuyển đổi các chuỗi nhiều hơn một khoảng trắng thành một tab, nhưng để riêng các không gian riêng lẻ :

sed 's/ \+ /\t/g' inputfile > outputfile

Để làm điều này cho một số tệp:

for inputfile in *
do
    sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done

hoặc là

for inputfile in *
do
    sed -i.bak 's/ \+ /\t/g' "$inputfile"
done

hoặc là

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;

sed: -e expression #1, char 1: unknown command: `.'
Aaron Franke

@AaronFranke: Bạn đã thử lệnh nào? Không có ví dụ nào trong câu trả lời của tôi sẽ tạo ra lỗi đó.
Tạm dừng cho đến khi có thông báo mới.

Xin lỗi, tôi nên làm rõ. Một findcái ở phía dưới.
Aaron Franke

@AaronFranke: GNU sedkhông muốn có một khoảng trắng trước phần mở rộng sao lưu. Tôi đã chỉnh sửa câu trả lời của mình. Cảm ơn báo cáo.
Tạm dừng cho đến khi có thông báo mới.

6

Nếu nhân vật của bạn là nhiều tab, bạn cũng có thể sử dụng tr -s:

-s, --squeeze-repeats   replace each input sequence of a repeated character
                        that is listed in SET1 with a single occurrence

Ví dụ:

my_file.txt | tr -s " "

Tất cả các khoảng trắng sẽ trở thành một.


Đây không phải là những gì OP đang yêu cầu.
RonJohn

5

Bạn có thể sử dụng sedđể thay thế một số khoảng trắng bằng một tab.:

Ví dụ để thay thế một hoặc nhiều khoảng trắng bằng một tab:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file

OP cho biết số lượng không gian là khác nhau , vì vậy tôi không nghĩ giải pháp này sẽ hiệu quả.
Mikel

@Mikel. Rất tiếc. Cảm ơn đã chỉ ra rằng. Tôi đã chỉnh sửa bài đăng để cho phép khớp với các không gian thay đổi.
IvanGoneKrazy

Câu trả lời hữu ích nhất ở đây.
Luís de Sousa

3

Câu trả lời đơn giản nhất chỉ sử dụng bashlà:

while read -r col1 col2 col3 ...; do
    echo -e "$col1\t$col2\t$col3..."
done <file

Nếu có một số lượng cột khác nhau, bạn có thể làm điều này, nhưng nó sẽ chỉ hoạt động bashchứ không phải sh:

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <file

ví dụ

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <<EOF
a b   c
d   e    f
  g h i
EOF

sản xuất:

a   b   c
d   e   f
g   h   i

(có một tab ở giữa mỗi cái, nhưng thật khó để nhìn thấy khi tôi dán nó ở đây)

Bạn cũng có thể làm điều đó bằng cách sử dụng sedhoặc tr, nhưng lưu ý rằng việc xử lý khoảng trống khi bắt đầu tạo ra kết quả khác nhau.

sed:

$ sed 's/  */\t/g' << EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i

tr:

$ tr -s ' ' '\t' <<EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i


2

Hãy thử tập lệnh SED sau:

 sed 's/  */<TAB>/g' <spaces-file > tabs-file

Trong đó <TAB> đang nhấn phím TAB.


0

Đây là một giải pháp rất đơn giản:

    sed -E 's/\s+/\t/g' your_file > new_file

Về cơ bản, sed hoạt động theo cách này (sed 's / old_potype / new_potype / g'). Trong trường hợp này, mẫu cũ là "\ s +" có nghĩa là tìm không gian "s" một hoặc nhiều lần "+" và dấu gạch chéo ngược "\" để diễn giải đó là biểu thức chính quy.
Mẫu mới là tab "\ t" được viết ở định dạng biểu thức chính quy và "g" được áp dụng thay thế cho tất cả các dòng "trên toàn cầu".


1
Xin chào và chào mừng đến với superuser. Bạn nên dành thời gian để giải thích giải pháp của bạn. Đối với một người không quen thuộc với các hệ thống * nix, sed và các biểu thức thông thường, điều này trông giống như một đống các ký tự kỳ lạ.
Mogget
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.