Bagaimana cara mengganti banyak spasi dengan satu tab

27

Saya memiliki beberapa file teks yang berisi beberapa kolom yang dipisahkan oleh berbagai jumlah ruang, tetapi saya membutuhkan satu tab tunggal sebagai pemisah. Apakah mungkin dilakukan di Bash?

Pengguna tidak diketahui
sumber
Terima kasih atas input yang bagus, tetapi saya memiliki beberapa spasi tunggal di dalam kolom, jadi saya harus menghindari tab spasi tunggal. maaf untuk itu, informasi.
user_unknown

Jawaban:

31

Untuk mengonversi urutan lebih dari satu ruang ke sebuah tab, tetapi tinggalkan ruang tersendiri :

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

Untuk melakukan ini untuk sejumlah file:

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

atau

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

atau

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
Dijeda sampai pemberitahuan lebih lanjut.
sumber
sed: -e expression #1, char 1: unknown command: `.'
Aaron Franke
@ AaronFranke: Perintah apa yang Anda coba? Tidak ada satu pun contoh dalam jawaban saya yang menghasilkan kesalahan itu.
Dijeda sampai pemberitahuan lebih lanjut.
Maaf, saya harus mengklarifikasi. Yang finddi bawah.
Aaron Franke
@AaronFranke: GNU sedtidak suka memiliki ruang sebelum ekstensi cadangan. Saya sudah mengedit jawaban saya. Terima kasih atas laporannya.
Dijeda sampai pemberitahuan lebih lanjut.
7

Jika karakter Anda banyak tab, Anda juga dapat menggunakan tr -s:

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

Sebagai contoh:

my_file.txt | tr -s " "

Semua ruang putih akan menjadi satu.

pengguna597119
sumber
Ini bukan yang diminta OP.
RonJohn
5

Anda dapat menggunakan seduntuk mengganti sejumlah spasi dengan tab .:

Contoh untuk mengganti satu-atau-lebih-spasi dengan satu tab:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
IvanGoneKrazy
sumber
OP mengatakan jumlah spasi bervariasi , jadi saya tidak berpikir solusi ini akan berhasil.
Mikel
@Mikel. Ups. Terima kasih telah menunjukkannya. Saya telah mengedit posting untuk memungkinkan pencocokan untuk ruang variabel.
IvanGoneKrazy
Jawaban paling berguna di sini.
Luís de Sousa
3

Jawaban termudah hanya menggunakan bashadalah:

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

Jika ada sejumlah variabel kolom, Anda bisa melakukan ini, tetapi itu hanya akan berfungsi bash, bukan sh:

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

misalnya

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

menghasilkan:

a   b   c
d   e   f
g   h   i

(ada tab di antara masing-masing, tetapi sulit untuk melihat ketika saya menempelkannya di sini)

Anda juga bisa melakukannya menggunakan sedatau tr, tetapi perhatikan bahwa penanganan kosong pada awalnya menghasilkan hasil yang berbeda.

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
Mikel
sumber
2

perl -p -i -e 's/\s+/\t/g' *.txt

RedGrittyBrick
sumber
2

Coba skrip SED berikut:

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

Di mana <TAB> menekan tombol TAB.

mdpc
sumber
0

Ini adalah solusi yang sangat sederhana:

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

sed pada dasarnya bekerja dengan cara ini (sed 's / old_pattern / new_pattern / g'). Dalam kasus ini pola lama adalah "\ s +" yang berarti menemukan spasi "s" satu atau lebih "+" dan garis miring "\" untuk menafsirkannya sebagai ekspresi reguler.
Pola baru adalah tab "\ t" yang ditulis dalam format ekspresi reguler dan "g" menerapkan penggantian ke semua baris "secara global".

Waleed Omer
sumber
1
Halo dan selamat datang di superuser. Anda harus meluangkan waktu untuk menjelaskan solusi Anda. Untuk seseorang yang tidak terbiasa dengan sistem * nix, sed dan ekspresi reguler, ini terlihat seperti tumpukan karakter aneh.
Mogget