Substitua os espaços em branco por guias no Linux


98

Como faço para substituir espaços em branco por guias no Linux em um determinado arquivo de texto?

Respostas:


168

Use o programa não expandido (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'').

4
Woah, nunca soube que existia expandir / não expandir. Eu estava tentando fazer o oposto e expandir era perfeito, ao invés de ter que mexer com trou sed.
Ibrahim

4
Para o registro, expandir / não expandir são utilitários padrão .
kojiro

4
Tão legal que esses são padrão. Eu amo a filosofia UNIX . Seria bom se pudesse fazer no lugar.
Matthew Flaschen

3
Não acho que não expandido funcione aqui .. ele só converte os espaços iniciais
olala

13
Apenas um aviso - o não expandido não converterá um único espaço em uma guia. Se você precisa converter cegamente todas as execuções de caracteres 0x20 em uma única guia, você precisa de uma ferramenta diferente.
Steve S.

44

Eu acho que você pode tentar com awk

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

ou SED se você preferir

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

ou mesmo tr

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

ou uma versão simplificada da solução tr sugerida por Sam Bisbee

tr ' ' \\t < someFile > someFile

4
Em seu exemplo sed, as práticas recomendadas ditam que você use tr para substituir caracteres únicos em vez de sed por razões de eficiência / velocidade. Além disso, o exemplo tr é muito mais fácil desta maneira:tr ' ' \\t < someFile > someFile
Sam Bisbee

2
Claro, tr tem melhor desempenho do que sed, mas a principal razão que tenho para amar o Unix é que existem muitas maneiras de fazer algo. Se você planeja fazer esta substituição muitas vezes buscará uma solução com bom desempenho, mas se for fazer apenas uma vez, buscará uma solução que envolve um comando que o deixará confortável.
Jonathan,

2
arg. Tive que usar tentativa e erro para fazer o sed funcionar. Não tenho ideia de por que tive que escapar do sinal de mais assim:ls -l | sed "s/ \+/ /g"
Jess

Com awk -v OFS="\t" '$1=$1' file1percebi que se você tem uma linha começando com o número 0 (por exemplo 0 1 2), a linha será omitida do resultado.
Nikola Novak

@Jess Você encontrou o regex da "sintaxe padrão correta". Por padrão, o sed trata o sinal de adição único (sem escape) como um caractere simples. O mesmo é verdadeiro para alguns outros caracteres como '?', ... Você pode encontrar mais informações aqui: gnu.org/software/sed/manual/html_node/… . Detalhes de sintaxe semelhantes podem ser encontrados aqui (observe que este é man for grep, não sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Victor Yarema

11

Usando Perl :

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

3
Tive um problema semelhante ao substituir espaços consecutivos por uma única guia. Perl funcionou com apenas a adição de um '+' ao regexp.
Todd

Embora, é claro, eu quisesse fazer o oposto: converter tabulações em dois espaços:perl -p -i -e 's/\t/ /g' *.java
TimP

Posso fazer isso recursivamente?
Aaron Franke

9

melhor comando tr :

tr [:blank:] \\t

Isso limpará a saída de, digamos, descompactar -l , para processamento posterior com grep, cut, etc.

por exemplo,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar

Não preciso usar aspas para fazê-lo funcionar:tr [:blank:] \\t
Ömer An

3

Faça download e execute o seguinte script para converter recursivamente as guias virtuais em guias rígidas em arquivos de texto simples.

Coloque e execute o script de dentro da pasta que contém os arquivos de texto simples.

#!/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;

2

Exemplo de comando para converter cada arquivo .js no diretório atual em tabs (apenas espaços iniciais são convertidos):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;

Testado no cygwin no Windows 7.
arkod

1

Você também pode usar astyle. Achei bastante útil e tem várias opções também:

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.`

0

Se você está falando sobre substituir todos os espaços consecutivos em uma linha por uma tabulação, então 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

Se você está falando sobre a substituição de todos os espaços em branco (por exemplo, espaço, tabulação, nova linha, etc.), então 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  

Se você está falando sobre como consertar um arquivo danificado por tab, use expande unexpandconforme mencionado em outras respostas.


0

Usando sed :

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

ou

sed "s/[[:space:]]\+/$T/g"

-1

Isso substituirá os espaços consecutivos por um espaço (mas não a tabulação).

tr -s '[:blank:]'

Isso substituirá os espaços consecutivos por uma tabulação.

tr -s '[:blank:]' '\t'

Na verdade, com o -cele substitui caracteres consecutivos que não são espaços.
wingedsubmariner

1
A questão é sobre guias, isso não é uma resposta.
Mateus Leia
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.