Ganti spasi putih dengan tab di linux

99

Bagaimana cara mengganti spasi putih dengan tab di linux dalam file teks tertentu?

biznez
sumber

Jawaban:

169

Gunakan program unexpand (1)


UNEXPAND(1)                      User Commands                     UNEXPAND(1)

NAME
       unexpand - convert spaces to tabs

SYNOPSIS
       unexpand [OPTION]... [FILE]...

DESCRIPTION
       Convert  blanks in each FILE to tabs, writing to standard output.  With
       no FILE, or when FILE is -, read standard input.

       Mandatory arguments to long options are  mandatory  for  short  options
       too.

       -a, --all
              convert all blanks, instead of just initial blanks

       --first-only
              convert only leading sequences of blanks (overrides -a)

       -t, --tabs=N
              have tabs N characters apart instead of 8 (enables -a)

       -t, --tabs=LIST
              use comma separated LIST of tab positions (enables -a)

       --help display this help and exit

       --version
              output version information and exit
. . .
STANDARDS
       The expand and unexpand utilities conform to IEEE Std 1003.1-2001
       (``POSIX.1'').
DigitalRoss
sumber
4
Woah, tidak pernah tahu ada ekspansi / unexpand. Saya mencoba melakukan yang sebaliknya dan berkembang sempurna daripada harus bermain-main dengan tratau sed.
Ibrahim
4
Sebagai catatan, expand / unexpand adalah utilitas standar .
kojiro
4
Sangat keren sehingga ini standar. Saya suka filosofi UNIX . Alangkah baiknya jika bisa dilakukan di tempat sekalipun.
Matthew Flaschen
3
Saya tidak berpikir unexpand akan bekerja di sini .. ini hanya mengubah spasi terdepan dan hanya dengan dua atau lebih spasi .. lihat di sini: lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
olala
13
Hanya hati-hati - unexpand tidak akan mengubah satu spasi pun menjadi tab. Jika Anda perlu mengonversi semua karakter 0x20 yang berjalan secara membabi buta menjadi satu tab, Anda memerlukan alat yang berbeda.
Steve S.
44

Saya pikir Anda bisa mencoba dengan awk

awk -v OFS="\t" '$1=$1' file1

atau SED jika Anda lebih suka

sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt

atau bahkan tr

tr -s '\t' < thefile.txt | tr '\t' ' ' > the_modified_copy.txt

atau versi sederhana dari solusi tr yang disarankan oleh Sam Bisbee

tr ' ' \\t < someFile > someFile
Jonathan
sumber
4
Dalam contoh sed Anda, praktik terbaik mendikte bahwa Anda menggunakan tr untuk mengganti karakter tunggal daripada sed untuk alasan efisiensi / kecepatan. Juga, contoh tr jauh lebih mudah dengan cara ini:tr ' ' \\t < someFile > someFile
Sam Bisbee
2
Tentu saja, tr memiliki kinerja yang lebih baik daripada sed, tetapi alasan utama saya menyukai Unix adalah ada banyak cara untuk melakukan sesuatu. Jika Anda berencana untuk melakukan substitusi ini berkali-kali, Anda akan mencari solusi dengan kinerja yang baik, tetapi jika Anda akan melakukannya hanya sekali, Anda akan mencari solusi yang melibatkan perintah yang membuat Anda merasa nyaman.
Jonathan
2
arg. Saya harus menggunakan trial and error untuk membuat sed bekerja. Saya tidak tahu mengapa saya harus melepaskan diri dari tanda plus seperti ini:ls -l | sed "s/ \+/ /g"
Jess
Dengan awk -v OFS="\t" '$1=$1' file1saya perhatikan bahwa jika Anda memiliki garis yang dimulai dengan angka 0 (misalnya 0 1 2), maka garis tersebut akan dihilangkan dari hasil.
Nikola Novak
@Jess Anda menemukan regex "sintaks default yang benar". Secara default sed perlakukan tanda plus tunggal (tidak lolos) sebagai karakter sederhana. Hal yang sama berlaku untuk beberapa karakter lain seperti '?', ... Anda dapat menemukan info selengkapnya di sini: gnu.org/software/sed/manual/html_node/… . Detail sintaks yang serupa dapat ditemukan di sini (perhatikan bahwa ini adalah man untuk grep, bukan sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Victor Yarema
12

Menggunakan Perl :

perl -p -i -e 's/ /\t/g' file.txt
John Millikin
sumber
3
Punya masalah serupa dengan mengganti spasi berurutan dengan satu tab. Perl bekerja hanya dengan penambahan '+' ke regexp.
Todd
Meskipun, tentu saja, saya ingin melakukan yang sebaliknya: ubah tab menjadi dua spasi:perl -p -i -e 's/\t/ /g' *.java
TimP
Bisakah saya melakukan ini secara rekursif?
Aaron Franke
Ini adalah satu-satunya varian yang berhasil untuk saya; Saya biasa s/ {4}/mengubah indentasi 4 ruang menjadi tab.
CrazyPyro
10

perintah tr yang lebih baik :

tr [:blank:] \\t

Ini akan membersihkan keluaran say, unzip -l , untuk diproses lebih lanjut dengan grep, cut, dll.

misalnya,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Tarkin
sumber
Saya tidak perlu menggunakan tanda kutip untuk membuatnya bekerja:tr [:blank:] \\t
Ömer An
3

Unduh dan jalankan skrip berikut untuk secara rekursif mengonversi tab lunak ke tab keras dalam file teks biasa.

Tempatkan dan jalankan skrip dari dalam folder yang berisi file teks biasa.

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(unexpand --first-only -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;
daka
sumber
2

Contoh perintah untuk mengonversi setiap file .js di bawah direktori saat ini ke tab (hanya spasi di depan yang dikonversi):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
arkod
sumber
Diuji di cygwin pada windows 7.
arkod
1

Anda juga bisa menggunakan astyle. Saya merasa ini cukup berguna dan memiliki beberapa opsi juga:

Tab and Bracket Options:
   If  no  indentation  option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4.  If no brackets option is set, the
   brackets will not be changed.

   --indent=spaces, --indent=spaces=#, -s, -s#
          Indent using # spaces per indent. Between 1 to 20.  Not specifying # will result in a default of 4 spaces per indent.

   --indent=tab, --indent=tab=#, -t, -t#
          Indent using tab characters, assuming that each tab is # spaces long.  Between 1 and 20. Not specifying # will result in a default assumption  of
          4 spaces per tab.`
Ankur Agarwal
sumber
0

Jika Anda berbicara tentang mengganti semua spasi berurutan pada baris dengan tab, maka tr -s '[:blank:]' '\t'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda
Device         Start
/dev/sda1       2048
/dev/sda2     411648
/dev/sda3    2508800
/dev/sda4   10639360
/dev/sda5   75307008
/dev/sda6   96278528
/dev/sda7  115809778
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t'
Device  Start
/dev/sda1       2048
/dev/sda2       411648
/dev/sda3       2508800
/dev/sda4       10639360
/dev/sda5       75307008
/dev/sda6       96278528
/dev/sda7       115809778

Jika Anda berbicara tentang mengganti semua spasi (misalnya spasi, tab, baris baru, dll.) Maka tr -s '[:space:]'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t'
Device  Start   /dev/sda1       2048    /dev/sda2       411648  /dev/sda3       2508800 /dev/sda4       10639360        /dev/sda5       75307008        /dev/sda6     96278528        /dev/sda7       115809778  

Jika Anda berbicara tentang memperbaiki file yang rusak tab, gunakan expanddan unexpandseperti yang disebutkan dalam jawaban lain.

lihai
sumber
0

Menggunakan sed :

T=$(printf "\t")
sed "s/[[:blank:]]\+/$T/g"

atau

sed "s/[[:space:]]\+/$T/g"
Tibor
sumber
-1

Ini akan menggantikan spasi berurutan dengan satu spasi (tetapi bukan tab).

tr -s '[:blank:]'

Ini akan mengganti spasi berurutan dengan tab.

tr -s '[:blank:]' '\t'
mel
sumber
Sebenarnya, dengan -citu menggantikan karakter berurutan yang bukan spasi.
wingedsubmariner
1
Pertanyaannya adalah tentang tab, ini bukan jawaban.
Matius Baca