w przypadku przestrzeni wizualnej, która jest kombinacją tabulatorów i spacji, to podejście daje niepoprawne rozwinięcie.
pizza
7
Dodałbym także dopasowywanie plików, takie jak na przykład tylko dla plików .php find ./ -iname "* .php" -type f -exec sed -i 's / \ t / / g' {} \;
Daniel Luca CleanUnicorn
98
NIE UŻYWAJ SED! Jeśli w ciągu znajduje się osadzona karta, może to skończyć się błędnym kodowaniem. To właśnie miało obsługiwać polecenie rozwijania . Zastosowanie expand.
David W.
5
@DavidW. Chciałbym po prostu zaktualizować to polecenie, aby zastąpić tabulatory tylko od początku wiersza. find ./ -type f -exec sed -i 's/^\t/####/g' {} \;. Ale nie wiedziałem o poleceniu rozwijania - bardzo przydatne!
Martin Konecny
29
NIE UŻYWAĆ! Ta odpowiedź właśnie zniszczyła moje lokalne repozytorium git. Jeśli masz pliki zawierające mieszane tabulatory i spacje, wstawi sekwencje #. Zamiast tego użyj odpowiedzi Gene'a lub komentarza Doge poniżej.
marionetka
344
Prosta wymiana sedjest w porządku, ale nie jest najlepszym możliwym rozwiązaniem. Jeśli między zakładkami znajdują się „dodatkowe” spacje, nadal będą one występować po zamianie, więc marginesy będą nierówne. Karty rozszerzone w środku linii również nie będą działać poprawnie. W bash, możemy powiedzieć, zamiast
do zastosowania expanddo każdego pliku Java w bieżącym drzewie katalogów. Usuń / zamień -nameargument, jeśli celujesz na inne typy plików. Jak wspomina jeden z komentarzy, zachowaj ostrożność podczas usuwania -namelub używania słabej, wieloznacznej karty. Możesz z łatwością zamykać repozytorium i inne ukryte pliki bez intencji. Oto dlaczego pierwotna odpowiedź zawierała to:
Zawsze powinieneś wykonać kopię zapasową drzewa przed wypróbowaniem czegoś takiego na wypadek, gdyby coś poszło nie tak.
@JeffreyMartinez Świetne pytanie. gniourf_gniourf zredagował moją oryginalną odpowiedź 11 listopada i wypowiedział obraźliwe uwagi na temat braku znajomości właściwego sposobu korzystania {}. Wygląda na to, że nie wiedział, $0kiedy -cjest używany. Następnie dimo414 zmienił się z mojego użycia temp w katalogu konwersji na /tmp, który będzie znacznie wolniejszy, jeśli /tmpbędzie w innym punkcie montowania. Niestety nie mam dostępnego Linux-a do przetestowania twojej $0propozycji. Ale myślę, że masz rację.
Gene,
1
@Gene, dzięki za wyjaśnienie, które brzmi jak stackoverflow w porządku: p. Chociaż jestem przy tym, dodam, że musiałem używać cudzysłowów wokół „* .java”, aby właściwie uciec z * .java.
Jeffrey Martinez
2
Jeśli ktoś ma błąd „nieznany główny lub operator” podczas wyszukiwania, oto pełne polecenie, które to naprawi:find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
Doży
4
Pomyślałem, że ta odpowiedź nie ma wystarczająco dużo komentarzy, więc jest moja: jeśli skorzystasz spongez joeyh.name/code/moreutils , możesz napisaćfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
tokland
8
Nie bądź głupi i używaj find . -name '*', właśnie zniszczyłem moje lokalne repozytorium git
Możesz użyć ogólnie dostępnego prpolecenia ( tutaj strona podręcznika ). Na przykład, aby przekonwertować tabulatory na cztery spacje, wykonaj następujące czynności:
pr -t -e=4 file > file.expanded
-t pomija nagłówki
-e=numrozwija tabulatory do numspacji
Aby rekurencyjnie przekonwertować wszystkie pliki w drzewie katalogów, pomijając pliki binarne:
#!/bin/bash
num=4
shopt -s globstar nullglob
for f in**/*;do[[-f "$f"]]||continue# skip if not a regular file! grep -qI "$f"&&continue# skip binary files
pr -t -e=$num "$f">"$f.expanded.$$"&& mv "$f.expanded.$$""$f"done
Logika pomijania plików binarnych pochodzi z tego postu .
UWAGA:
Może to być niebezpieczne w repozytorium git lub svn
Nie jest to właściwe rozwiązanie, jeśli masz pliki kodu, których tabulatory są osadzone w literałach łańcuchowych
Czy jest jakaś przewaga nad expandtym, że oba są POSIX? Np. Czy ma wbudowaną opcję zmiany? Git safety at: stackoverflow.com/a/52136507/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
5
Jak przekonwertować tabulatory na spacje w każdym pliku katalogu (ewentualnie rekurencyjnie)?
Zwykle nie jest to, czego chcesz.
Czy chcesz to zrobić dla obrazów PNG? Pliki PDF? Katalog .git? Twój
Makefile(który wymaga zakładek)? Zrzut SQL 5 GB?
Teoretycznie możesz przekazać wiele opcji wykluczania findlub cokolwiek innego, czego używasz; ale jest to kruche i zepsuje się, gdy tylko dodasz inne pliki binarne.
Co chcesz, to co najmniej:
Pomiń pliki o określonym rozmiarze.
Wykryj, czy plik jest binarny, sprawdzając obecność bajtu NULL.
Zastępuj tabulatory tylko na początku pliku ( expandrobi to, sed
nie robi).
O ile mi wiadomo, nie ma „standardowego” narzędzia uniksowego, które mogłoby to zrobić i nie jest to bardzo łatwe w przypadku powłoki jednowierszowej, więc potrzebny jest skrypt.
Jakiś czas temu stworzyłem mały skrypt o nazwie
sanitize_files, który właśnie to robi. Naprawia również kilka innych rzeczy jak zastąpienie wspólnego \r\nz \ndodanie końcowego znaku \n, itd.
Możesz znaleźć uproszczony skrypt bez dodatkowych funkcji i argumentów wiersza poleceń poniżej, ale zalecamy użycie powyższego skryptu, ponieważ jest bardziej prawdopodobne, że otrzyma poprawki błędów i inne zaktualizowane niż ten post.
Chciałbym również wskazać, w odpowiedzi na niektóre inne odpowiedzi tutaj, że użycie globowania powłoki nie jest solidnym sposobem na zrobienie tego, ponieważ wcześniej czy później skończy się więcej plików, niż zmieści się ARG_MAX(w nowoczesnych Systemy Linux to 128k, co może wydawać się dużo, ale wcześniej czy później to nie
wystarczy).
#!/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)
Podoba mi się powyższy przykład „znajdź” dla aplikacji rekurencyjnej. Aby dostosować go tak, aby nie był rekurencyjny, zmieniając tylko pliki w bieżącym katalogu, które pasują do znaku wieloznacznego, rozszerzenie globu powłoki może być wystarczające dla małych ilości plików:
ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh -v
Jeśli chcesz to cichy po ufasz, że to działa, po prostu upuść -vna shpolecenia na końcu.
Oczywiście możesz wybrać dowolny zestaw plików w pierwszym poleceniu. Na przykład, wypisz tylko określony podkatalog (lub katalogi) w kontrolowany sposób:
ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh
Lub z kolei uruchom find (1) z pewną kombinacją parametrów głębokości itp .:
Globowanie powłoki załamie się wcześniej czy później, ponieważ całkowita liczba nazw plików może być tylko ARG_MAXdługa. Jest to 128k w systemach Linux, ale napotkałem ten limit wystarczająco dużo razy, aby nie polegać na globowaniu powłoki.
Martin Tournoij,
1
Naprawdę nie musisz ich dostosowywać. findmożna powiedzieć -maxdepth 1, i przetwarza tylko wpisy modyfikowanego katalogu, a nie całe drzewo.
ShadowRanger
4
Użyłem astyledo re-indent wszyscy moi C / C ++ kod po znalezieniu mieszane kart i spacji. Ma także opcje wymuszenia określonego stylu nawiasów, jeśli chcesz.
Jak stwierdził Carpetsmoker, nastąpi zmiana w zależności od twoich vimustawień. I modeliny w plikach, jeśli istnieją. Ponadto zastąpi tabulatory nie tylko na początku linii. Którego na ogół nie chcesz. Na przykład możesz mieć literały zawierające tabulatory.
:retabzmieni wszystkie zakładki w pliku, a nie te na początku. zależy to również od tego, jakie są twoje ustawienia :tabstopi :expandtabustawienia w vimrc lub modeline, więc może to wcale nie działać.
Martin Tournoij,
@Carpetsmoker Dobra uwaga na temat kart na początku linii. Czy którekolwiek z rozwiązań tutaj obsługuje ten przypadek? Jeśli chodzi o ustawienia tabstopi expandtab, zadziała, jeśli używasz vim. Chyba że w plikach znajdują się linie trybu.
x-yuri,
@ x-yuri dobre pytanie, ale generalnie dyskusyjne. Większość ludzi nie używa rzeczywistych zakładek w literałach.
Ricardo Cruz,
4
Polecam użyć:
find .-name '*.lua'-exec ex '+%s/\t/ /g'-cwq {} \;
Komentarze:
Użyj edycji na miejscu. Przechowuj kopie zapasowe w VCS. Nie trzeba tworzyć plików * .orig. Dobrą praktyką jest różnicowanie wyniku względem ostatniego zatwierdzenia, aby upewnić się, że zadziałało zgodnie z oczekiwaniami.
sedjest edytorem strumieniowym. Użyj exdo edycji na miejscu. Pozwala to uniknąć tworzenia dodatkowych plików tymczasowych i odradzania powłok dla każdej zamiany, jak w pliku pierwszej odpowiedzi .
OSTRZEŻENIE: Spełnia to wszystkie zakładki, nie tylko te używane do wcięcia. Nie zmienia też kontekstowego zastępowania kart. To wystarczyło w moim przypadku użycia. Ale może być dla ciebie nie do przyjęcia.
EDIT: Wcześniejsza wersja tej odpowiedzi używany find|xargszamiast find -exec. Jak wskazał @ gniourf-gniourf, prowadzi to do problemów ze spacjami, cudzysłowami i znakami kontrolnymi w nazwach plików por. Wheeler .
exmoże nie być dostępny w każdym systemie Unix. Zastąpienie go vi -emoże działać na większej liczbie komputerów. Ponadto wyrażenie regularne zamienia dowolną liczbę początkowych znaków tabulacji na dwie spacje. Zamień wyrażenie regularne na, +%s/\t/ /gaby nie niszczyć wielopoziomowego wcięcia. Wpływa to jednak również na znaki tabulacji, które nie są używane do wcięcia.
Lukas Schmelzeisen
ex jest częścią POSIX [1], więc powinna być dostępna. Dobra uwaga na temat indukcji wielopoziomowej. W rzeczywistości użyłem tego /\t/ /wariantu w moich plikach, ale zdecydowałem /\t\+//się nie łamać tabulatorów bez wcięć. Pominięto problemy z wielokrotnym wcięciem! Aktualizacja odpowiedzi. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSO
Heinrich Hartmann
2
Używanie xargsw ten sposób jest bezużyteczne, nieefektywne i zepsute (pomyśl o nazwach plików zawierających spacje lub cudzysłowy). Dlaczego nie używacie find„s -execprzełącznik zamiast?
gniourf_gniourf
Twierdziłbym, że nazwy plików ze spacjami i cudzysłowami są zepsute; ) Jeśli potrzebujesz wsparcia, które wybrałbym: -print0opcje find / xargs. Lubię xargs -execod kiedy: a) Rozdzielenie obaw b) można łatwiej zamieniać GNU równolegle.
Czym różni się ta odpowiedź od tej, która została opublikowana 4 lata temu?
PP
2
Twoja odpowiedź też. W rzeczywistości jest to gorsza wersja odpowiedzi Gene'a: 1) Odpowiedź Gene'a zajmuje się katalogami o tej samej nazwie. 2) Nie porusza się, jeśli rozszerzenie nie powiedzie się.
Spowodowało to uszkodzenie wszystkich plików binarnych w moim repozytorium.
Aaron Franke,
1
Doskonałe polecenie, ale potencjalnie niebezpieczne z opcją rekursywną i wszystkimi plikami w folderze, jak określono powyżej. Dodałbym opcję --dry-run „na wszelki wypadek”, aby upewnić się, że siedzisz we właściwym folderze.
MortimerCat
2
Zastosowanie, expandjak sugerowano w innych odpowiedziach, wydaje się najbardziej logicznym podejściem do samego zadania.
To powiedziawszy, można to również zrobić za pomocą Bash i Awk, na wypadek, gdybyś mógł chcieć wprowadzić inne modyfikacje wraz z nim.
Jeśli używasz Bash 4.0 lub nowszego, wbudowanego shoptglobstar można używać do wyszukiwania rekurencyjnego **.
W GNU Awk w wersji 4.1 lub nowszej można wprowadzać modyfikacje plików typu „inplace”:
Oczywiście ilość miejsca, na które powiększa się karta, zależy od kontekstu. Sed jest więc całkowicie nieodpowiednim narzędziem do tego zadania.
Sven
?? @ Sev, moja komenda sed robi to samo, co komenda expand ( expand -t 4 input >output)
Makah
3
Oczywiście nie. expand -t 4powiększy tabulator a\tbdo 3 spacji, a tab aa\tbdo 2 spacji, tak jak powinien być. expandbierze pod uwagę kontekst karty, sednie zastępuje i zastępuje określoną przez Ciebie ilością spacji, niezależnie od kontekstu.
Sven
-1
Użyj vim-way:
$ ex +'bufdo retab'-cxa **/*.*
Wykonaj kopię zapasową! przed wykonaniem powyższego polecenia, ponieważ może to spowodować uszkodzenie plików binarnych.
Aby użyć globstar( **) do rekurencji, aktywuj za pomocą shopt -s globstar.
Aby określić konkretny typ pliku, należy użyć np **/*.c.
... a wszystkie twoje rozwiązania będą blokować pliki binarne i takie (jak pliki .png, pliki .pdf itp.)
Martin Tournoij
Jest to szczerze mówiąc okropna sugestia dla dokumentacji - trzeba dokładnie zapoznać się z szeregiem dość nieprzejrzystej składni i problemów semantycznych kilku programów, aby móc to zrozumieć.
pr
to wspaniałe narzędzie do tego. Zobacz tę odpowiedź .Odpowiedzi:
find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +
Oryginalny plik zostanie zapisany jako
[filename].orig
.Zamień „* .java” na końcówkę pliku, którego szukasz. W ten sposób można zapobiec przypadkowemu uszkodzeniu plików binarnych.
Wady:
źródło
expand
.find ./ -type f -exec sed -i 's/^\t/####/g' {} \;
. Ale nie wiedziałem o poleceniu rozwijania - bardzo przydatne!Prosta wymiana
sed
jest w porządku, ale nie jest najlepszym możliwym rozwiązaniem. Jeśli między zakładkami znajdują się „dodatkowe” spacje, nadal będą one występować po zamianie, więc marginesy będą nierówne. Karty rozszerzone w środku linii również nie będą działać poprawnie. Wbash
, możemy powiedzieć, zamiastdo zastosowania
expand
do każdego pliku Java w bieżącym drzewie katalogów. Usuń / zamień-name
argument, jeśli celujesz na inne typy plików. Jak wspomina jeden z komentarzy, zachowaj ostrożność podczas usuwania-name
lub używania słabej, wieloznacznej karty. Możesz z łatwością zamykać repozytorium i inne ukryte pliki bez intencji. Oto dlaczego pierwotna odpowiedź zawierała to:źródło
{}
. Wygląda na to, że nie wiedział,$0
kiedy-c
jest używany. Następnie dimo414 zmienił się z mojego użycia temp w katalogu konwersji na/tmp
, który będzie znacznie wolniejszy, jeśli/tmp
będzie w innym punkcie montowania. Niestety nie mam dostępnego Linux-a do przetestowania twojej$0
propozycji. Ale myślę, że masz rację.find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
sponge
z joeyh.name/code/moreutils , możesz napisaćfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
find . -name '*'
, właśnie zniszczyłem moje lokalne repozytorium gitWypróbuj narzędzie wiersza polecenia
expand
.gdzie
-i
służy do rozwijania tylko wiodących kart w każdej linii;-t 4
oznacza, że każda karta zostanie przekonwertowana na 4 znaki białych znaków (domyślnie 8).sponge
pochodzi zmoreutils
pakietu i pozwala uniknąć czyszczenia pliku wejściowego .Wreszcie możesz korzystać
gexpand
z systemu OSX po instalacji zacoreutils
pomocą Homebrew (brew install coreutils
).źródło
-i
do,expand
aby zastąpić tylko wiodące tabulatory w każdej linii. Pomaga to uniknąć zamiany kart, które mogą być częścią kodu.input
jest tym samym plikiem, cooutput
bash blokuje zawartość, zanim jeszcze się uruchomiexpand
. Tak to>
działa.Zbieranie najlepszych komentarzy z odpowiedzi Gene'a , najlepszym jak dotąd najlepszym rozwiązaniem jest korzystanie
sponge
z moreutils .Wyjaśnienie:
./
rekurencyjnie szuka z bieżącego katalogu-iname
jest dopasowanie bez rozróżniania wielkości liter (dla obu*.java
i*.JAVA
polubień)type -f
znajduje tylko zwykłe pliki (bez katalogów, plików binarnych lub dowiązań symbolicznych)-exec bash -c
wykonaj następujące polecenia w podpowłoce dla każdej nazwy pliku,{}
expand -t 4
rozszerza wszystkie tabele do 4 pólsponge
wchłonąć standardowe wejście (zexpand
) i zapisać do pliku (tego samego) *.UWAGA : * Proste przekierowanie pliku (
> "$0"
) nie będzie tutaj działać, ponieważ zbyt wcześnie nadpisze plik .Zaleta : wszystkie oryginalne uprawnienia do plików są zachowane i nie
tmp
są używane żadne pliki pośrednie .źródło
Użyj znaku odwrotnego ukośnika
sed
.W systemie Linux:
Zamień wszystkie karty na 1 łącznik na miejscu we wszystkich plikach * .txt:
Zamień wszystkie karty na 1 miejsce w miejscu, we wszystkich plikach * .txt:
Zamień wszystkie tabulatory na 4 spacje we wszystkich plikach * .txt:
Na komputerze Mac:
Zamień wszystkie tabulatory na 4 spacje we wszystkich plikach * .txt:
źródło
sed -i '' $'s/\t/ /g' $(find . -name "*.txt")
Możesz użyć ogólnie dostępnego
pr
polecenia ( tutaj strona podręcznika ). Na przykład, aby przekonwertować tabulatory na cztery spacje, wykonaj następujące czynności:-t
pomija nagłówki-e=num
rozwija tabulatory donum
spacjiAby rekurencyjnie przekonwertować wszystkie pliki w drzewie katalogów, pomijając pliki binarne:
Logika pomijania plików binarnych pochodzi z tego postu .
UWAGA:
źródło
expand
tym, że oba są POSIX? Np. Czy ma wbudowaną opcję zmiany? Git safety at: stackoverflow.com/a/52136507/895245Zwykle nie jest to, czego chcesz.
Czy chcesz to zrobić dla obrazów PNG? Pliki PDF? Katalog .git? Twój
Makefile
(który wymaga zakładek)? Zrzut SQL 5 GB?Teoretycznie możesz przekazać wiele opcji wykluczania
find
lub cokolwiek innego, czego używasz; ale jest to kruche i zepsuje się, gdy tylko dodasz inne pliki binarne.Co chcesz, to co najmniej:
expand
robi to,sed
nie robi).O ile mi wiadomo, nie ma „standardowego” narzędzia uniksowego, które mogłoby to zrobić i nie jest to bardzo łatwe w przypadku powłoki jednowierszowej, więc potrzebny jest skrypt.
Jakiś czas temu stworzyłem mały skrypt o nazwie sanitize_files, który właśnie to robi. Naprawia również kilka innych rzeczy jak zastąpienie wspólnego
\r\n
z\n
dodanie końcowego znaku\n
, itd.Możesz znaleźć uproszczony skrypt bez dodatkowych funkcji i argumentów wiersza poleceń poniżej, ale zalecamy użycie powyższego skryptu, ponieważ jest bardziej prawdopodobne, że otrzyma poprawki błędów i inne zaktualizowane niż ten post.
Chciałbym również wskazać, w odpowiedzi na niektóre inne odpowiedzi tutaj, że użycie globowania powłoki nie jest solidnym sposobem na zrobienie tego, ponieważ wcześniej czy później skończy się więcej plików, niż zmieści się
ARG_MAX
(w nowoczesnych Systemy Linux to 128k, co może wydawać się dużo, ale wcześniej czy później to nie wystarczy).źródło
Podoba mi się powyższy przykład „znajdź” dla aplikacji rekurencyjnej. Aby dostosować go tak, aby nie był rekurencyjny, zmieniając tylko pliki w bieżącym katalogu, które pasują do znaku wieloznacznego, rozszerzenie globu powłoki może być wystarczające dla małych ilości plików:
Jeśli chcesz to cichy po ufasz, że to działa, po prostu upuść
-v
nash
polecenia na końcu.Oczywiście możesz wybrać dowolny zestaw plików w pierwszym poleceniu. Na przykład, wypisz tylko określony podkatalog (lub katalogi) w kontrolowany sposób:
Lub z kolei uruchom find (1) z pewną kombinacją parametrów głębokości itp .:
źródło
ARG_MAX
długa. Jest to 128k w systemach Linux, ale napotkałem ten limit wystarczająco dużo razy, aby nie polegać na globowaniu powłoki.find
można powiedzieć-maxdepth 1
, i przetwarza tylko wpisy modyfikowanego katalogu, a nie całe drzewo.Użyłem
astyle
do re-indent wszyscy moi C / C ++ kod po znalezieniu mieszane kart i spacji. Ma także opcje wymuszenia określonego stylu nawiasów, jeśli chcesz.źródło
Można
vim
do tego użyć :Jak stwierdził Carpetsmoker, nastąpi zmiana w zależności od twoich
vim
ustawień. I modeliny w plikach, jeśli istnieją. Ponadto zastąpi tabulatory nie tylko na początku linii. Którego na ogół nie chcesz. Na przykład możesz mieć literały zawierające tabulatory.źródło
:retab
zmieni wszystkie zakładki w pliku, a nie te na początku. zależy to również od tego, jakie są twoje ustawienia:tabstop
i:expandtab
ustawienia w vimrc lub modeline, więc może to wcale nie działać.tabstop
iexpandtab
, zadziała, jeśli używaszvim
. Chyba że w plikach znajdują się linie trybu.Polecam użyć:
Komentarze:
sed
jest edytorem strumieniowym. Użyjex
do edycji na miejscu. Pozwala to uniknąć tworzenia dodatkowych plików tymczasowych i odradzania powłok dla każdej zamiany, jak w pliku pierwszej odpowiedzi .find|xargs
zamiastfind -exec
. Jak wskazał @ gniourf-gniourf, prowadzi to do problemów ze spacjami, cudzysłowami i znakami kontrolnymi w nazwach plików por. Wheeler .źródło
ex
może nie być dostępny w każdym systemie Unix. Zastąpienie govi -e
może działać na większej liczbie komputerów. Ponadto wyrażenie regularne zamienia dowolną liczbę początkowych znaków tabulacji na dwie spacje. Zamień wyrażenie regularne na,+%s/\t/ /g
aby nie niszczyć wielopoziomowego wcięcia. Wpływa to jednak również na znaki tabulacji, które nie są używane do wcięcia./\t/ /
wariantu w moich plikach, ale zdecydowałem/\t\+//
się nie łamać tabulatorów bez wcięć. Pominięto problemy z wielokrotnym wcięciem! Aktualizacja odpowiedzi. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSOxargs
w ten sposób jest bezużyteczne, nieefektywne i zepsute (pomyśl o nazwach plików zawierających spacje lub cudzysłowy). Dlaczego nie używaciefind
„s-exec
przełącznik zamiast?-print0
opcje find / xargs. Lubię xargs-exec
od kiedy: a) Rozdzielenie obaw b) można łatwiej zamieniać GNU równolegle.Aby przekonwertować rekurencyjnie wszystkie pliki Java w katalogu, tak aby używały 4 spacji zamiast tabulacji:
źródło
Można skorzystać
find
ztabs-to-spaces
pakietu do tego.Najpierw zainstaluj
tabs-to-spaces
następnie uruchom to polecenie z katalogu głównego swojego projektu;
Spowoduje to zastąpienie każdego
tab
znaku wartością 2spaces
w każdym pliku.źródło
Nie wspomniano o ciele
rpl
? Za pomocą rpl możesz zamienić dowolny ciąg. Aby przekonwertować tabulatory na spacje,bardzo prosty.
źródło
Zastosowanie,
expand
jak sugerowano w innych odpowiedziach, wydaje się najbardziej logicznym podejściem do samego zadania.To powiedziawszy, można to również zrobić za pomocą Bash i Awk, na wypadek, gdybyś mógł chcieć wprowadzić inne modyfikacje wraz z nim.
Jeśli używasz Bash 4.0 lub nowszego, wbudowanego shopt
globstar
można używać do wyszukiwania rekurencyjnego**
.W GNU Awk w wersji 4.1 lub nowszej można wprowadzać modyfikacje plików typu „inplace”:
Jeśli chcesz ustawić liczbę spacji na zakładkę:
źródło
Pobierz i uruchom następujący skrypt, aby rekurencyjnie konwertować twarde karty na miękkie karty w zwykłych plikach tekstowych.
Uruchom skrypt z folderu zawierającego zwykłe pliki tekstowe.
źródło
Metoda przyjazna dla repozytorium Git
Działaj na wszystkie pliki w bieżącym katalogu:
Działaj tylko na plikach C lub C ++:
Prawdopodobnie chcesz tego, szczególnie z powodu tych irytujących plików Makefile, które wymagają zakładek.
Polecenie
git grep --cached -Il ''
:.git
jak wyjaśniono na: Jak wyświetlić listę wszystkich plików tekstowych (niebinarnych) w repozytorium git?
chmod --reference
uprawnienia do plików pozostają niezmienione: /unix/20645/clone-ownership-and-permissions-from-another-file Niestety nie mogę znaleźć zwięzłej alternatywy POSIX .Jeśli twoja baza kodu wpadła na szalony pomysł, aby zezwolić na funkcjonalne nieprzetworzone tabulacje w łańcuchach, użyj:
a potem baw się dobrze, przeglądając kolejno wszystkie nie uruchamiane karty linii, które możesz wypisać: Czy można używać grep dla kart?
Testowane na Ubuntu 18.04.
źródło
Konwersja tabulatorów na spacje w plikach „.lua” [tabs -> 2 spacje]
źródło
expand -t 4 input >output
)expand -t 4
powiększy tabulatora\tb
do 3 spacji, a tabaa\tb
do 2 spacji, tak jak powinien być.expand
bierze pod uwagę kontekst karty,sed
nie zastępuje i zastępuje określoną przez Ciebie ilością spacji, niezależnie od kontekstu.Użyj vim-way:
globstar
(**
) do rekurencji, aktywuj za pomocąshopt -s globstar
.**/*.c
.Aby zmodyfikować tabstop, dodaj
+'set ts=2'
.Jednak wadą jest to, że może zastąpić zakładki wewnątrz ciągów .
Aby uzyskać nieco lepsze rozwiązanie (przy użyciu podstawienia), spróbuj:
Lub za pomocą
ex
edytora +expand
narzędzie:Aby zobaczyć końcowe spacje, zobacz: Jak usunąć końcowe białe spacje dla wielu plików?
Możesz dodać następującą funkcję do swojego
.bash_profile
:źródło
:retab
może w ogóle nie działać , globowanie powłoki jest złym rozwiązaniem dla tego rodzaju rzeczy , twoje:s
polecenie zastąpi dowolną liczbę tabulatorów 2 spacjami (które prawie nigdy nie chcę), rozpoczęcie ex po prostu uruchomienia:!expand
procesu jest głupie ...