Zastąp białe znaki tabulatorami w systemie Linux

99

Jak zamienić spacje na tabulatory w Linuksie w danym pliku tekstowym?

biznez
źródło

Odpowiedzi:

169

Użyj programu unexand (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
źródło
4
Woah, nigdy nie wiedziałem, że istnieje rozszerzenie / nierozszerzenie. Próbowałem zrobić coś odwrotnego i ekspansja była idealna, zamiast mieszać się z trlub sed.
Ibrahim,
4
Dla przypomnienia, expand / u expand to standardowe narzędzia .
kojiro
4
Tak fajnie, że są standardowe. Uwielbiam filozofię UNIX . Byłoby miło, gdyby można to zrobić na miejscu.
Matthew Flaschen
3
Nie sądzę, że metoda nierozszerzania będzie działać tutaj .. konwertuje tylko początkowe
olala
13
Tylko uwaga - operacja rozwijania nie spowoduje konwersji pojedynczej spacji na kartę. Jeśli chcesz na ślepo przekonwertować wszystkie serie znaków 0x20 na jedną kartę, potrzebujesz innego narzędzia.
Steve S.
44

Myślę, że możesz spróbować z awk

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

lub SED, jeśli wolisz

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

lub nawet tr

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

lub uproszczona wersja roztworu tr zasugerowanego przez Sama Bisbee

tr ' ' \\t < someFile > someFile
Jonathan
źródło
4
W twoim przykładzie z sedem, najlepsze praktyki nakazują używanie tr do zastępowania pojedynczych znaków zamiast seda ze względu na wydajność / szybkość. Również przykład tr jest znacznie łatwiejszy w ten sposób:tr ' ' \\t < someFile > someFile
Sam Bisbee,
2
Oczywiście tr ma lepszą wydajność niż sed, ale głównym powodem, dla którego kocham Uniksa, jest to, że jest wiele sposobów na zrobienie czegoś. Jeśli planujesz wykonać tę zamianę wiele razy, będziesz szukać rozwiązania z dobrą wydajnością, ale jeśli zamierzasz to zrobić tylko raz, będziesz szukać rozwiązania, które obejmuje polecenie, które sprawi, że poczujesz się komfortowo.
Jonathan,
2
arg. Musiałem użyć prób i błędów, aby sed działał. Nie mam pojęcia, dlaczego musiałem uciec przed znakiem plus w ten sposób:ls -l | sed "s/ \+/ /g"
Jess
Z awk -v OFS="\t" '$1=$1' file1Zauważyłem, że jeśli masz początek wiersza o numerze 0 (np 0 1 2), wówczas linia zostanie pominięta z wyniku.
Nikola Novak
@Jess Znalazłeś wyrażenie regularne „poprawna domyślna składnia”. Domyślnie sed traktuje pojedynczy (bez zmiany znaczenia) znak plus jako zwykły znak. To samo dotyczy niektórych innych znaków, takich jak „?”, ... Więcej informacji można znaleźć tutaj: gnu.org/software/sed/manual/html_node/… . Podobne szczegóły dotyczące składni można znaleźć tutaj (zwróć uwagę, że jest to man dla grepa , a nie sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Victor Yarema
12

Korzystanie z Perla :

perl -p -i -e 's/ /\t/g' file.txt
John Millikin
źródło
3
Miałem podobny problem z zamianą kolejnych spacji na jedną tabulator. Perl działał tylko z dodatkiem „+” do wyrażenia regularnego.
Todd
Chociaż, oczywiście, chciałem zrobić coś odwrotnego: przekonwertować tabulatory na dwie spacje:perl -p -i -e 's/\t/ /g' *.java
TimP,
Czy mogę to zrobić rekurencyjnie?
Aaron Franke
To był jedyny wariant, który działał dla mnie; Kiedyś s/ {4}/konwertowałem wcięcia z 4 spacjami na tabulatory.
CrazyPyro
10

lepsze polecenie tr :

tr [:blank:] \\t

Spowoduje to wyczyszczenie danych wyjściowych polecenia powiedzmy unzip -l do dalszego przetwarzania za pomocą grep, cut itp.

na przykład,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Tarkin
źródło
Nie muszę używać cudzysłowów, żeby to zadziałało:tr [:blank:] \\t
Ömer An
3

Pobierz i uruchom następujący skrypt, aby rekurencyjnie konwertować miękkie karty na twarde w zwykłych plikach tekstowych.

Umieść i uruchom skrypt z wnętrza folderu zawierającego zwykłe pliki tekstowe.

#!/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
źródło
2

Przykładowe polecenie konwersji każdego pliku .js z bieżącego katalogu na tabulatory (konwertowane są tylko spacje początkowe):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
arkod
źródło
Testowane w Cygwin w
systemie
1

Możesz także użyć astyle. Uważam, że jest całkiem przydatny i ma też kilka opcji:

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
źródło
0

Jeśli mówisz o zastąpieniu wszystkich kolejnych spacji w wierszu tabulatorem, to 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

Jeśli mówisz o zamianie wszystkich białych znaków (np. Spacja, tabulator, nowa linia, itp.) To 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  

Jeśli mówisz o naprawianiu pliku uszkodzonego na karcie, użyj expandi unexpandjak wspomniano w innych odpowiedziach.

złośnica
źródło
0

Korzystanie sed :

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

lub

sed "s/[[:space:]]\+/$T/g"
Tibor
źródło
-1

Spowoduje to zastąpienie kolejnych spacji jedną spacją (ale nie tabulatorem).

tr -s '[:blank:]'

Spowoduje to zastąpienie kolejnych spacji tabulatorem.

tr -s '[:blank:]' '\t'
mel
źródło
Właściwie -cto zastępuje kolejne znaki, które nie są spacjami.
wingedsubmariner
1
Pytanie dotyczy zakładek, to nie jest odpowiedź.
Matthew Przeczytaj