para o espaço visual que é uma mistura de guias e espaços, essa abordagem fornece expansão incorreta.
pizza
7
Eu também adicionaria um comparador de arquivos como, por exemplo, apenas para arquivos .php encontrar ./-nome "* .php" -tipo f -exec sed -i 's / \ t / / g' {} \;
Daniel Luca CleanUnicorn
98
NÃO USE SED! Se houver uma guia incorporada em uma string, você pode acabar manipulando seu código. É com isso que o comando de expansão foi criado. Use expand.
David W.
5
@DavidW. Eu simplesmente atualizaria este comando para substituir apenas as guias desde o início da linha. find ./ -type f -exec sed -i 's/^\t/####/g' {} \;. Mas eu não estava ciente do comando de expansão - muito útil!
Martin Konecny
29
NÃO USE! Esta resposta também acabou com o meu repositório git local. Se você tiver arquivos contendo guias e espaços misturados, ele inserirá sequências de # 's. Use a resposta de Gene ou o comentário de Doge abaixo.
fantoche
344
A substituição simples por sedestá correta, mas não é a melhor solução possível. Se houver espaços "extras" entre as guias, eles ainda estarão lá após a substituição, portanto as margens serão irregulares. Guias expandidas no meio das linhas também não funcionarão corretamente. Em bash, podemos dizer em vez disso
para aplicar expanda todos os arquivos Java na árvore de diretórios atual. Remova / substitua o -nameargumento se você estiver direcionando outros tipos de arquivo. Como um dos comentários menciona, tenha muito cuidado ao remover -nameou usar um caractere curinga fraco. Você pode facilmente recuperar repositórios e outros arquivos ocultos sem intenção. É por isso que a resposta original incluiu isso:
Você sempre deve fazer uma cópia de segurança da árvore antes de tentar algo assim, caso algo dê errado.
@JeffreyMartinez Great question. gniourf_gniourf editou minha resposta original em 11 de novembro e fez comentários depreciativos sobre não saber a maneira correta de usar {}. Parece que ele não sabia $0quando -cé usado. Em seguida, o dimo414 mudou do meu uso de um temp no diretório de conversão para /tmp, que será muito mais lento se /tmpestiver em um ponto de montagem diferente. Infelizmente, não tenho uma caixa Linux disponível para testar sua $0proposta. Mas acho que você está correto.
Gene
1
@Gene, obrigado pelo esclarecimento, isso soa como um stackoverflow certo: p. Enquanto estou no assunto, acrescentarei que tive que usar aspas em torno de '* .java' para escapar adequadamente do * .java.
Jeffrey Martinez
2
Se alguém está a ter um erro 'desconhecido primária ou operador' do achado, então aqui é o comando completo que irá corrigi-lo:find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
Doge
4
Eu pensei que esta resposta não tinha comentários suficientes como era, por isso esta é minha: se o uso de uso spongede joeyh.name/code/moreutils , você pode escreverfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
tokland
8
Não seja estúpido e uso find . -name '*', eu só destruiu o meu local repo git
Gautam
193
Experimente a ferramenta de linha de comando expand.
expand -i -t 4 input | sponge output
Onde
-i é usado para expandir apenas as guias principais em cada linha;
-t 4 significa que cada guia será convertida em 4 caracteres de espaço em branco (8 por padrão).
Você deve passar -ipara expandpara substituir apenas as guias principais em cada linha. Isso ajuda a evitar a substituição de guias que podem fazer parte do código.
Perguntas Quolonel
10
que tal recursivamente para cada arquivo em um diretório?
ahnbizcad
4
Toda vez que tento usar isso, apaga alguns (geralmente todos) dos arquivos. : \
ThorSummoner
5
@ ThorSummoner: se inputé o mesmo arquivo que outputo bash clobbers o conteúdo antes mesmo de começar expand. É assim que >funciona.
Robert Siemer
34
Coletando os melhores comentários de resposta de Gene , a melhor solução, de longe, é usando spongede moreutils .
Alguma vantagem, expanddado que ambos são POSIX? Por exemplo, tem uma opção de alteração em linha? Git
security
5
Como posso converter guias em espaços em todos os arquivos de um diretório (possivelmente recursivamente)?
Isso geralmente não é o que você deseja.
Deseja fazer isso para imagens png? Arquivos PDF? O diretório .git? Seu
Makefile(que requer guias)? Um dump SQL de 5 GB?
Você poderia, em teoria, passar muitas opções de exclusão para findou o que quer que esteja usando; mas isso é frágil e será interrompido assim que você adicionar outros arquivos binários.
O que você quer é pelo menos:
Pule arquivos acima de um determinado tamanho.
Detecte se um arquivo é binário, verificando a presença de um byte NULL.
Substitua apenas as guias no início de um arquivo ( expandisso sed
não ocorre).
Até onde eu sei, não existe um utilitário Unix "padrão" que possa fazer isso, e não é muito fácil fazer isso com um liner de shell, portanto é necessário um script.
Há um tempo atrás, criei um pequeno script chamado
sanitize_files, que faz exatamente isso. Ele também corrige outras coisas comuns, como substituir \r\npor \n, adicionar um final \n, etc.
Você pode encontrar um script simplificado sem os recursos extras e os argumentos da linha de comando abaixo, mas eu recomendo que você use o script acima, pois é mais provável que você receba correções de bugs e outras atualizações atualizadas além desta publicação.
Eu também gostaria de salientar, em resposta a algumas das outras respostas aqui, que o uso de globbing de shell não é uma maneira robusta de fazer isso, porque mais cedo ou mais tarde você terá mais arquivos do que o necessário ARG_MAX(nos modernos sistemas Linux é 128k, que pode parecer muito, mas mais cedo ou mais tarde, é não
suficiente).
#!/usr/bin/env python## http://code.arp242.net/sanitize_files#
import os, re, sys
def is_binary(data):return data.find(b'\000')>=0
def should_ignore(path):
keep =[# VCS systems'.git/','.hg/''.svn/''CVS/',# These files have significant whitespace/tabs, and cannot be edited# safely# TODO: there are probably more of these files..'Makefile','BSDmakefile','GNUmakefile','Gemfile.lock']for k in keep:if'/%s'% k in path:returnTruereturnFalse
def run(files):
indent_find = b'\t'
indent_replace = b' '* indent_width
for f in files:if should_ignore(f):
print('Ignoring %s'% f)continue
try:
size = os.stat(f).st_size
# Unresolvable symlink, just ignore those
except FileNotFoundError as exc:
print('%s is unresolvable, skipping (%s)'%(f, exc))continueif size ==0:continueif size >1024**2:
print("Skipping `%s' because it's over 1MiB"% f)continue
try:
data = open(f,'rb').read()
except (OSError,PermissionError) as exc:
print("Error: Unable to read `%s': %s"%(f, exc))continueif is_binary(data):
print("Skipping `%s' because it looks binary"% f)continue
data = data.split(b'\n')
fixed_indent =Falsefor i, line in enumerate(data):# Fix indentation
repl_count =0while line.startswith(indent_find):
fixed_indent =True
repl_count +=1
line = line.replace(indent_find, b'',1)if repl_count >0:
line = indent_replace * repl_count + line
data = list(filter(lambda x: x is not None, data))
try:
open(f,'wb').write(b'\n'.join(data))
except (OSError,PermissionError) as exc:
print("Error: Unable to write to `%s': %s"%(f, exc))if __name__ =='__main__':
allfiles =[]for root, dirs, files in os.walk(os.getcwd()):for f in files:
p ='%s/%s'%(root, f)if do_add:
allfiles.append(p)
run(allfiles)
Eu gosto do exemplo "find" acima para o aplicativo recursivo. Para adaptá-lo para não ser recursivo, alterando apenas os arquivos no diretório atual que correspondem a um curinga, a expansão do shell glob pode ser suficiente para pequenas quantidades de arquivos:
ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh -v
Se você deseja silenciá-lo depois de confiar que ele funciona, basta soltar -vo shcomando no final.
Claro que você pode escolher qualquer conjunto de arquivos no primeiro comando. Por exemplo, liste apenas um subdiretório (ou diretórios) específico de uma maneira controlada como esta:
ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh
Ou, por sua vez, execute find (1) com alguma combinação de parâmetros de profundidade, etc:
O globbing do shell quebrará mais cedo ou mais tarde, porque a quantidade total de nomes de arquivos pode ter apenas o ARG_MAXcomprimento. Isso é 128k em sistemas Linux, mas eu encontrei esse limite o tempo suficiente para não confiar no globbing do shell.
Martin Tournoij 12/08/2015
1
Você realmente não precisa adaptá-los. findpode ser informado -maxdepth 1e processa apenas as entradas do diretório que está sendo modificado, não a árvore inteira.
ShadowRanger
4
Eu costumava astylereentrar todo o meu código C / C ++ depois de encontrar guias e espaços mistos. Ele também possui opções para forçar um estilo de chave específico, se você desejar.
Como o Carpetsmoker declarou, ele fará uma nova revisão de acordo com vim configurações. E modelos nos arquivos, se houver. Além disso, substituirá as guias não apenas no início das linhas. O que não é o que você geralmente deseja. Por exemplo, você pode ter literais, contendo guias.
:retabalterará todas as guias de um arquivo, não aquelas no início. também depende de quais são suas configurações :tabstope :expandtabno vimrc ou modeline, portanto, isso pode não funcionar.
Martin Tournoij 12/08/2015
@Carpetsmoker Bom argumento sobre as guias no início das linhas. Alguma das soluções aqui lida com esse caso? Quanto às configurações tabstope expandtab, funcionará se você estiver usando vim. A menos que você tenha linhas de modo nos arquivos.
X-yuri
@ x-yuri boa pergunta, mas geralmente discutível. A maioria das pessoas usa guias não reais em literais.
Ricardo Cruz
4
Minha recomendação é usar:
find .-name '*.lua'-exec ex '+%s/\t/ /g'-cwq {} \;
Comentários:
Use a edição no local. Mantenha backups em um VCS. Não há necessidade de produzir arquivos * .orig. É uma boa prática diferenciar o resultado do seu último commit para garantir que funcione conforme o esperado, em qualquer caso.
sedé um editor de stream. Use expara edição no local. Isso evita a criação de arquivos temporários extras e conchas de desova para cada substituição, como na resposta superior .
AVISO: Isso interfere em todas as guias, não apenas nas usadas para recuo. Além disso, ele não substitui as guias com reconhecimento de contexto. Isso foi suficiente para o meu caso de uso. Mas pode não ser aceitável para você.
EDIT: Uma versão anterior desta resposta usada em find|xargsvez de find -exec. Como apontado por @ gniourf-gniourf, isso leva a problemas com espaços, aspas e caracteres de controle nos nomes de arquivos, cf. Wheeler .
expode não estar disponível em todos os sistemas Unix. Substituí-lo por vi -epode funcionar em mais máquinas. Além disso, seu regex substitui qualquer número de caracteres da guia inicial por dois espaços. Substitua o regex por +%s/\t/ /gnão destruir o recuo de vários níveis. No entanto, isso também afeta os caracteres de tabulação que não são usados para indentação.
Lukas Schmelzeisen
ex faz parte do POSIX [1], portanto deve estar disponível. Bom ponto sobre indendação de vários níveis. Na verdade, eu havia usado a /\t/ /variante em meus arquivos, mas optei por /\t\+//não quebrar guias não recuadas. Perdeu os problemas com a multi-indentação! Atualizando a resposta. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSO
Heinrich Hartmann
2
Usar xargsdessa maneira é inútil, ineficiente e quebrado (pense em nomes de arquivos que contenham espaços ou aspas). Por que você não usa findo -execcomutador?
gniourf_gniourf
Eu diria que nomes de arquivos com espaços e aspas estão quebrados; ) Se você precisar apoiar, eu optaria por: -print0opções para encontrar / xargs. Gosto do xargs -execdesde: a) Separação de preocupações b) pode ser trocado com o GNU paralelo mais facilmente.
Como isso é diferente resposta de esta que foi publicado há 4 anos?
PP
2
O mesmo acontece com a sua resposta. De fato, esta é uma versão inferior da resposta de Gene: 1) A resposta de Gene cuida de diretórios com o mesmo nome. 2) Não se move se a expansão falhar.
PP
4
Você pode usar findcom o tabs-to-spacespacote para isso.
Primeiro, instale tabs-to-spaces
npm install -g tabs-to-spaces
em seguida, execute este comando no diretório raiz do seu projeto;
find .-name '*'-exec t2s --spaces 2{} \;
Isso substituirá cada tabcaractere por 2 spacesem cada arquivo.
Isso corrompeu todos os arquivos binários no meu repositório.
Aaron Franke
1
Um comando excelente, mas potencialmente perigoso com a opção recursiva e todos os arquivos na pasta, conforme especificado acima. Eu adicionaria a opção --dry-run "apenas no caso" para garantir que você esteja sentado na pasta correta.
MortimerCat
2
O uso de expand como sugerido em outras respostas parece a abordagem mais lógica para esta tarefa sozinha.
Dito isto, também pode ser feito com o Bash e o Awk, caso você queira fazer outras modificações.
Se estiver usando o Bash 4.0 ou superior, o shopt internoglobstar pode ser usado para pesquisar recursivamente **.
Com o GNU Awk versão 4.1 ou superior, é possível fazer modificações no arquivo "inplace":
Obviamente, a quantidade de espaço que uma guia se expande depende do contexto. Assim, sed é uma ferramenta completamente inadequada para a tarefa.
Sven
?? @Sven, meu comando sed faz a mesma coisa que o comando expand ( expand -t 4 input >output)
Makah
3
Claro que não. expand -t 4expandirá a guia em a\tb3 espaços e a guia em aa\tb2 espaços, exatamente como deveria ser. expandleva em consideração o contexto de uma guia, sednão substitui e substituirá a guia pela quantidade de espaços que você especificar, independentemente do contexto.
Sven
-1
Use o vim-way:
$ ex +'bufdo retab'-cxa **/*.*
Faça o backup! antes de executar o comando acima, pois ele pode corromper seus arquivos binários.
Para usar globstar( **) para recursão, ative por shopt -s globstar.
Para especificar o tipo de arquivo específico, use por exemplo: **/*.c.
Eu diminuí o voto de muitas respostas neste tópico, não apenas o seu ;-) Os motivos são: :retabpode não funcionar , shell globbing é uma solução ruim para esse tipo de coisa , seu :scomando substituirá qualquer quantidade de guias por 2 espaços (que você quase nunca quero), começando ex só para executar um :!expandprocesso é bobagem ...
Martin Tournoij
... e todas as suas soluções vai espancar arquivos binários e tal (como arquivos .png, arquivos .pdf, etc.)
Martin Tournoij
Essa é francamente uma sugestão horrível para a documentação - é preciso familiarizar-se intimamente com uma série de questões bastante opacas de sintaxe e semântica de vários programas para poder entender isso.
pr
é uma utilidade maravilhosa para isso. Veja esta resposta .Respostas:
find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +
O arquivo original é salvo como
[filename].orig
.Substitua '* .java' pelo final do arquivo que você está procurando. Dessa forma, você pode impedir a corrupção acidental de arquivos binários.
Desvantagens:
fonte
expand
.find ./ -type f -exec sed -i 's/^\t/####/g' {} \;
. Mas eu não estava ciente do comando de expansão - muito útil!A substituição simples por
sed
está correta, mas não é a melhor solução possível. Se houver espaços "extras" entre as guias, eles ainda estarão lá após a substituição, portanto as margens serão irregulares. Guias expandidas no meio das linhas também não funcionarão corretamente. Embash
, podemos dizer em vez dissopara aplicar
expand
a todos os arquivos Java na árvore de diretórios atual. Remova / substitua o-name
argumento se você estiver direcionando outros tipos de arquivo. Como um dos comentários menciona, tenha muito cuidado ao remover-name
ou usar um caractere curinga fraco. Você pode facilmente recuperar repositórios e outros arquivos ocultos sem intenção. É por isso que a resposta original incluiu isso:fonte
{}
. Parece que ele não sabia$0
quando-c
é usado. Em seguida, o dimo414 mudou do meu uso de um temp no diretório de conversão para/tmp
, que será muito mais lento se/tmp
estiver em um ponto de montagem diferente. Infelizmente, não tenho uma caixa Linux disponível para testar sua$0
proposta. Mas acho que você está correto.find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
sponge
de joeyh.name/code/moreutils , você pode escreverfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
find . -name '*'
, eu só destruiu o meu local repo gitExperimente a ferramenta de linha de comando
expand
.Onde
-i
é usado para expandir apenas as guias principais em cada linha;-t 4
significa que cada guia será convertida em 4 caracteres de espaço em branco (8 por padrão).sponge
é domoreutils
pacote e evita limpar o arquivo de entrada .Finalmente, você pode usar
gexpand
no OSX, depois de instalarcoreutils
com o Homebrew (brew install coreutils
).fonte
-i
paraexpand
para substituir apenas as guias principais em cada linha. Isso ajuda a evitar a substituição de guias que podem fazer parte do código.input
é o mesmo arquivo queoutput
o bash clobbers o conteúdo antes mesmo de começarexpand
. É assim que>
funciona.Coletando os melhores comentários de resposta de Gene , a melhor solução, de longe, é usando
sponge
de moreutils .Explicação:
./
está pesquisando recursivamente a partir do diretório atual-iname
é uma correspondência que não diferencia maiúsculas de minúsculas (para ambos*.java
e*.JAVA
gostos)type -f
localiza apenas arquivos regulares (sem diretórios, binários ou links simbólicos)-exec bash -c
execute os seguintes comandos em uma subshell para cada nome de arquivo,{}
expand -t 4
expande todos os TABs para 4 espaçossponge
absorva a entrada padrão (deexpand
) e grave em um arquivo (o mesmo) *.NOTA : * Um simples redirecionamento de arquivo (
> "$0"
) não funcionará aqui porque substituirá o arquivo muito cedo .Vantagem : Todas as permissões de arquivo originais são mantidas e nenhum
tmp
arquivo intermediário é usado.fonte
Use escape com barra invertida
sed
.No linux:
Substitua todas as guias por 1 hífen no local, em todos os arquivos * .txt:
Substitua todas as guias por 1 espaço no local, em todos os arquivos * .txt:
Substitua todas as guias com 4 espaços no local, em todos os arquivos * .txt:
Em um mac:
Substitua todas as guias com 4 espaços no local, em todos os arquivos * .txt:
fonte
sed -i '' $'s/\t/ /g' $(find . -name "*.txt")
Você pode usar o
pr
comando geralmente disponível (página de manual aqui ). Por exemplo, para converter guias em quatro espaços, faça o seguinte:-t
suprime cabeçalhos-e=num
expande guias paranum
espaçosPara converter todos os arquivos em uma árvore de diretórios recursivamente, ignorando arquivos binários:
A lógica para pular arquivos binários é desta postagem .
NOTA:
fonte
expand
dado que ambos são POSIX? Por exemplo, tem uma opção de alteração em linha? GitIsso geralmente não é o que você deseja.
Deseja fazer isso para imagens png? Arquivos PDF? O diretório .git? Seu
Makefile
(que requer guias)? Um dump SQL de 5 GB?Você poderia, em teoria, passar muitas opções de exclusão para
find
ou o que quer que esteja usando; mas isso é frágil e será interrompido assim que você adicionar outros arquivos binários.O que você quer é pelo menos:
expand
issosed
não ocorre).Até onde eu sei, não existe um utilitário Unix "padrão" que possa fazer isso, e não é muito fácil fazer isso com um liner de shell, portanto é necessário um script.
Há um tempo atrás, criei um pequeno script chamado sanitize_files, que faz exatamente isso. Ele também corrige outras coisas comuns, como substituir
\r\n
por\n
, adicionar um final\n
, etc.Você pode encontrar um script simplificado sem os recursos extras e os argumentos da linha de comando abaixo, mas eu recomendo que você use o script acima, pois é mais provável que você receba correções de bugs e outras atualizações atualizadas além desta publicação.
Eu também gostaria de salientar, em resposta a algumas das outras respostas aqui, que o uso de globbing de shell não é uma maneira robusta de fazer isso, porque mais cedo ou mais tarde você terá mais arquivos do que o necessário
ARG_MAX
(nos modernos sistemas Linux é 128k, que pode parecer muito, mas mais cedo ou mais tarde, é não suficiente).fonte
Eu gosto do exemplo "find" acima para o aplicativo recursivo. Para adaptá-lo para não ser recursivo, alterando apenas os arquivos no diretório atual que correspondem a um curinga, a expansão do shell glob pode ser suficiente para pequenas quantidades de arquivos:
Se você deseja silenciá-lo depois de confiar que ele funciona, basta soltar
-v
osh
comando no final.Claro que você pode escolher qualquer conjunto de arquivos no primeiro comando. Por exemplo, liste apenas um subdiretório (ou diretórios) específico de uma maneira controlada como esta:
Ou, por sua vez, execute find (1) com alguma combinação de parâmetros de profundidade, etc:
fonte
ARG_MAX
comprimento. Isso é 128k em sistemas Linux, mas eu encontrei esse limite o tempo suficiente para não confiar no globbing do shell.find
pode ser informado-maxdepth 1
e processa apenas as entradas do diretório que está sendo modificado, não a árvore inteira.Eu costumava
astyle
reentrar todo o meu código C / C ++ depois de encontrar guias e espaços mistos. Ele também possui opções para forçar um estilo de chave específico, se você desejar.fonte
Pode-se usar
vim
para isso:Como o Carpetsmoker declarou, ele fará uma nova revisão de acordo com
vim
configurações. E modelos nos arquivos, se houver. Além disso, substituirá as guias não apenas no início das linhas. O que não é o que você geralmente deseja. Por exemplo, você pode ter literais, contendo guias.fonte
:retab
alterará todas as guias de um arquivo, não aquelas no início. também depende de quais são suas configurações:tabstop
e:expandtab
no vimrc ou modeline, portanto, isso pode não funcionar.tabstop
eexpandtab
, funcionará se você estiver usandovim
. A menos que você tenha linhas de modo nos arquivos.Minha recomendação é usar:
Comentários:
sed
é um editor de stream. Useex
para edição no local. Isso evita a criação de arquivos temporários extras e conchas de desova para cada substituição, como na resposta superior .find|xargs
vez defind -exec
. Como apontado por @ gniourf-gniourf, isso leva a problemas com espaços, aspas e caracteres de controle nos nomes de arquivos, cf. Wheeler .fonte
ex
pode não estar disponível em todos os sistemas Unix. Substituí-lo porvi -e
pode funcionar em mais máquinas. Além disso, seu regex substitui qualquer número de caracteres da guia inicial por dois espaços. Substitua o regex por+%s/\t/ /g
não destruir o recuo de vários níveis. No entanto, isso também afeta os caracteres de tabulação que não são usados para indentação./\t/ /
variante em meus arquivos, mas optei por/\t\+//
não quebrar guias não recuadas. Perdeu os problemas com a multi-indentação! Atualizando a resposta. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSOxargs
dessa maneira é inútil, ineficiente e quebrado (pense em nomes de arquivos que contenham espaços ou aspas). Por que você não usafind
o-exec
comutador?-print0
opções para encontrar / xargs. Gosto do xargs-exec
desde: a) Separação de preocupações b) pode ser trocado com o GNU paralelo mais facilmente.Para converter todos os arquivos Java recursivamente em um diretório para usar 4 espaços em vez de uma guia:
fonte
Você pode usar
find
com otabs-to-spaces
pacote para isso.Primeiro, instale
tabs-to-spaces
em seguida, execute este comando no diretório raiz do seu projeto;
Isso substituirá cada
tab
caractere por 2spaces
em cada arquivo.fonte
Nenhum corpo mencionado
rpl
? Usando o rpl, você pode substituir qualquer string. Para converter guias em espaços,muito simples.
fonte
O uso de
expand
como sugerido em outras respostas parece a abordagem mais lógica para esta tarefa sozinha.Dito isto, também pode ser feito com o Bash e o Awk, caso você queira fazer outras modificações.
Se estiver usando o Bash 4.0 ou superior, o shopt interno
globstar
pode ser usado para pesquisar recursivamente**
.Com o GNU Awk versão 4.1 ou superior, é possível fazer modificações no arquivo "inplace":
Caso você queira definir o número de espaços por guia:
fonte
Faça o download e execute o script a seguir para converter recursivamente guias rígidas em guias flexíveis em arquivos de texto sem formatação.
Execute o script de dentro da pasta que contém os arquivos de texto sem formatação.
fonte
Método amigável ao repositório Git
Atue em todos os arquivos no diretório atual:
Atue apenas em arquivos C ou C ++:
Você provavelmente deseja isso principalmente por causa dos Makefiles irritantes que exigem guias.
O comando
git grep --cached -Il ''
:.git
como explicado em: Como listar todos os arquivos de texto (não binários) em um repositório git?
chmod --reference
mantém as permissões de arquivo inalteradas: /unix/20645/clone-ownership-and-permissions-from-another-file Infelizmente, não consigo encontrar uma alternativa POSIX sucinta .Se sua base de código teve a ideia maluca de permitir guias funcionais em strings, use:
e divirta-se examinando todas as guias que não são do início da linha, uma a uma, com as quais você pode listar: É possível obter o grep para as guias?
Testado no Ubuntu 18.04.
fonte
Convertendo guias em espaço apenas em arquivos ".lua" [guias -> 2 espaços]
fonte
expand -t 4 input >output
)expand -t 4
expandirá a guia ema\tb
3 espaços e a guia emaa\tb
2 espaços, exatamente como deveria ser.expand
leva em consideração o contexto de uma guia,sed
não substitui e substituirá a guia pela quantidade de espaços que você especificar, independentemente do contexto.Use o vim-way:
globstar
(**
) para recursão, ative porshopt -s globstar
.**/*.c
.Para modificar o tabstop, adicione
+'set ts=2'
.No entanto, o lado negativo é que ele pode substituir as guias dentro das strings .
Portanto, para uma solução um pouco melhor (usando substituição), tente:
Ou usando o
ex
editor +expand
utilitário:Para espaços à direita, consulte: Como remover espaços em branco à direita para vários arquivos?
Você pode adicionar a seguinte função ao seu
.bash_profile
:fonte
:retab
pode não funcionar , shell globbing é uma solução ruim para esse tipo de coisa , seu:s
comando substituirá qualquer quantidade de guias por 2 espaços (que você quase nunca quero), começando ex só para executar um:!expand
processo é bobagem ...