untuk ruang visual yang merupakan campuran tab dan spasi, pendekatan ini memberikan ekspansi yang salah.
pizza
7
Saya juga akan menambahkan pencocokan file seperti misalnya hanya untuk menemukan file .php ./ -iname "* .php" -type f -exec sed -i 's / \ t / / g' {} \;
Daniel Luca CleanUnicorn
98
JANGAN GUNAKAN SED! Jika ada tab yang disematkan dalam sebuah string, Anda mungkin berakhir menyusun kode Anda. Inilah yang perintah memperluas dimaksudkan untuk menangani. Gunakan expand.
David W.
5
@ DavidW. Saya hanya akan memperbarui perintah ini untuk hanya mengganti tab dari awal baris. find ./ -type f -exec sed -i 's/^\t/####/g' {} \;. Tapi saya tidak menyadari perintah memperluas - sangat berguna!
Martin Konecny
29
JANGAN GUNAKAN! Jawaban ini juga hanya merusak repositori git lokal saya. Jika Anda memiliki file yang berisi tab dan spasi campuran, itu akan menyisipkan urutan # 's. Gunakan jawaban oleh Gene atau komentar oleh Doge sebagai gantinya.
boneka
344
Penggantian sederhana dengan sedtidak apa-apa tapi bukan solusi terbaik. Jika ada ruang "ekstra" di antara tab, mereka akan tetap ada setelah penggantian, sehingga margin akan menjadi acak-acakan. Tab yang diperluas di tengah garis juga tidak akan berfungsi dengan benar. Di bash, kita bisa mengatakan sebaliknya
untuk diterapkan expandke setiap file Java di pohon direktori saat ini. Hapus / ganti -nameargumen jika Anda menargetkan beberapa jenis file lainnya. Seperti yang disebutkan dalam salah satu komentar, berhati-hatilah saat mengeluarkan -nameatau menggunakan kartu pengganti yang lemah. Anda dapat dengan mudah menerima repositori dan file tersembunyi lainnya tanpa sengaja. Inilah sebabnya mengapa jawaban asli termasuk ini:
Anda harus selalu membuat salinan cadangan pohon sebelum mencoba sesuatu seperti ini jika terjadi kesalahan.
@ JeffreyMartinez Pertanyaan bagus. gniourf_gniourf mengedit jawaban asli saya pada 11 November dan membuat komentar meremehkan tentang tidak mengetahui cara yang tepat untuk digunakan {}. Sepertinya dia tidak tahu $0kapan -cdigunakan. Kemudian dimo414 berubah dari penggunaan temp saya di direktori konversi menjadi /tmp, yang akan jauh lebih lambat jika /tmpberada pada titik mount yang berbeda. Sayangnya saya tidak memiliki kotak Linux yang tersedia untuk menguji $0proposal Anda . Tapi saya pikir Anda benar.
Gene
1
@ Gen, terima kasih atas klarifikasi, yang terdengar seperti stackoverflow, oke: p. Sementara saya melakukannya, saya akan menambahkan saya harus menggunakan tanda kutip di sekitar '* .java' untuk melarikan diri dari * .java.
Jeffrey Martinez
2
Jika ada yang mengalami kesalahan 'primer atau operator tidak dikenal' dari find, maka di sini adalah perintah lengkap yang akan memperbaikinya:find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
Doge
4
Saya pikir jawaban ini tidak memiliki komentar yang cukup, jadi ini milik saya: jika gunakan spongedari joeyh.name/code/moreutils , Anda dapat menulisfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
tokland
8
Jangan bodoh dan gunakan find . -name '*', saya baru saja menghancurkan git repo lokal saya
Anda harus beralih -ike expandhanya mengganti tab terkemuka di setiap baris. Ini membantu menghindari penggantian tab yang mungkin menjadi bagian dari kode.
Pertanyaan Quolonel
10
bagaimana dengan setiap file dalam direktori secara rekursif?
ahnbizcad
4
Setiap kali saya mencoba menggunakan ini, itu kosong beberapa (biasanya semua) file. : \
ThorSummoner
5
@ThorSummoner: if inputadalah file yang sama outputdengan bash clobbers konten bahkan sebelum memulai expand. Beginilah cara >kerjanya.
Robert Siemer
34
Mengumpulkan komentar terbaik dari jawaban Gene , solusi terbaik sejauh ini, adalah dengan menggunakan spongedari moreutils .
Anda dapat menggunakan prperintah yang tersedia secara umum (halaman manual di sini ). Misalnya, untuk mengonversi tab menjadi empat spasi, lakukan ini:
pr -t -e=4 file > file.expanded
-t menekan tajuk
-e=numperluas tab ke numspasi
Untuk mengonversi semua file di pohon direktori secara rekursif, sambil melewatkan file biner:
#!/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 untuk melewatkan file biner adalah dari posting ini .
CATATAN:
Melakukan ini bisa berbahaya dalam repo git atau svn
Ini bukan solusi yang tepat jika Anda memiliki file kode yang memiliki tab yang tertanam dalam string literal
Adakah keuntungan lebih dari expandmengingat bahwa keduanya POSIX? Misalnya apakah ada opsi perubahan sebaris? Git safety at: stackoverflow.com/a/52136507/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 事件 法轮功
5
Bagaimana saya bisa mengonversi tab menjadi spasi di setiap file direktori (mungkin secara rekursif)?
Ini biasanya bukan yang Anda inginkan.
Apakah Anda ingin melakukan ini untuk gambar png? File PDF? Direktori .git? Anda
Makefile(yang membutuhkan tab)? Dump SQL 5GB?
Secara teori, Anda bisa meneruskan banyak opsi pengecualian ke findatau apa pun yang Anda gunakan; tetapi ini rapuh, dan akan pecah segera setelah Anda menambahkan file biner lainnya.
Yang Anda inginkan, setidaknya:
Lewati file dengan ukuran tertentu.
Mendeteksi jika file biner dengan memeriksa keberadaan byte NULL.
Hanya ganti tab pada awal file ( expandapakah ini, sed
tidak).
Sejauh yang saya tahu, tidak ada utilitas Unix "standar" yang dapat melakukan ini, dan itu tidak mudah dilakukan dengan shell one-liner, jadi diperlukan skrip.
Beberapa waktu yang lalu saya membuat skrip kecil bernama
sanitize_files yang melakukan hal itu. Juga perbaikan beberapa hal umum lainnya seperti mengganti \r\ndengan \n, menambahkan Trailing \n, dll
Anda dapat menemukan skrip yang disederhanakan tanpa fitur tambahan dan argumen baris perintah di bawah ini, tetapi saya sarankan Anda menggunakan skrip di atas karena lebih mungkin untuk menerima perbaikan bug dan pembaruan lainnya daripada posting ini.
Saya juga ingin menunjukkan, dalam menanggapi beberapa jawaban lain di sini, bahwa menggunakan shell globbing bukanlah cara yang kuat untuk melakukan ini, karena cepat atau lambat Anda akan berakhir dengan lebih banyak file daripada yang akan cocok ARG_MAX(pada modern Sistem Linux 128k, yang mungkin tampak banyak, tetapi cepat atau lambat itu tidak
cukup).
#!/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)
Saya suka contoh "temukan" di atas untuk aplikasi rekursif. Untuk mengadaptasinya menjadi non-rekursif, hanya mengubah file di direktori saat ini yang cocok dengan wildcard, ekspansi glob shell bisa mencukupi untuk sejumlah kecil file:
ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh -v
Jika Anda ingin itu diam setelah Anda percaya bahwa itu berfungsi, cukup letakkan -vpada shperintah di akhir.
Tentu saja Anda dapat memilih set file dalam perintah pertama. Misalnya, daftar hanya subdirektori tertentu (atau direktori) dengan cara yang terkontrol seperti ini:
ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}'| sh
Atau pada gilirannya jalankan temukan (1) dengan beberapa kombinasi parameter kedalaman dll:
Shell globbing akan rusak cepat atau lambat, karena jumlah total nama file hanya ARG_MAXpanjang. Ini 128k pada sistem Linux, tetapi saya telah menemui batas ini cukup kali untuk tidak bergantung pada shell globbing.
Martin Tournoij
1
Anda tidak perlu menyesuaikannya. finddapat dikatakan -maxdepth 1, dan hanya memproses entri direktori yang sedang dimodifikasi, bukan seluruh pohon.
ShadowRanger
4
Saya digunakan astyleuntuk indentasi ulang semua kode C / C ++ saya setelah menemukan tab dan spasi campuran. Ia juga memiliki opsi untuk memaksa gaya penyangga tertentu jika Anda mau.
Seperti yang dinyatakan oleh Carpetsmoker, itu akan melakukan retab sesuai dengan vimpengaturan Anda . Dan modelines dalam file, jika ada. Juga, itu akan mengganti tab tidak hanya di awal baris. Yang bukan apa yang biasanya Anda inginkan. Misalnya, Anda mungkin memiliki literal, yang berisi tab.
:retabakan mengubah semua tab dalam file, bukan yang di awal. itu juga tergantung pada apa :tabstopdan :expandtabpengaturan Anda di vimrc atau modeline, jadi ini mungkin tidak berfungsi sama sekali.
Martin Tournoij
@Carpetsmoker Poin bagus tentang tab di awal baris. Apakah ada solusi di sini yang menangani kasus ini? Adapun pengaturan tabstopdan expandtab, itu akan berhasil jika Anda menggunakan vim. Kecuali jika Anda memiliki garis mode di file.
x-yuri
@ x-yuri pertanyaan bagus, tapi umumnya bisa diperdebatkan. Sebagian besar orang menggunakan bukan tab yang sebenarnya dalam literal.
Ricardo Cruz
4
Rekomendasi saya adalah menggunakan:
find .-name '*.lua'-exec ex '+%s/\t/ /g'-cwq {} \;
Komentar:
Gunakan pengeditan di tempat. Simpan cadangan dalam VCS. Tidak perlu menghasilkan file * .orig. Praktik yang baik untuk membedakan hasilnya dengan komit terakhir Anda untuk memastikan ini bekerja seperti yang diharapkan, dalam hal apa pun.
sedadalah editor aliran. Gunakan exuntuk mengedit di tempat. Ini menghindari membuat file temp tambahan dan spawning shells untuk setiap penggantian seperti pada jawaban teratas .
PERINGATAN: Ini mengacaukan semua tab, tidak hanya yang digunakan untuk indentasi. Juga tidak melakukan penggantian tab sadar konteks. Ini cukup untuk kasus penggunaan saya. Tetapi mungkin tidak dapat diterima untuk Anda.
EDIT: Versi sebelumnya dari jawaban ini digunakan find|xargssebagai ganti find -exec. Seperti yang ditunjukkan oleh @ gniourf-gniourf ini menyebabkan masalah dengan spasi, tanda kutip dan karakter kontrol dalam nama file cf. Wheeler .
exmungkin tidak tersedia di setiap sistem Unix. Mengganti dengan vi -emungkin bekerja pada lebih banyak mesin. Juga, regex Anda menggantikan sejumlah karakter tab awal dengan dua spasi. Ganti regex dengan +%s/\t/ /gtidak merusak lekukan multi level. Namun ini juga memengaruhi karakter tab yang tidak digunakan untuk indentasi.
Lukas Schmelzeisen
ex adalah bagian dari POSIX [1] jadi harus tersedia. Poin bagus tentang multi level indendation. Saya sebenarnya telah menggunakan /\t/ /varian pada file saya, tetapi memilih untuk /\t\+//tidak merusak tab yang tidak membuat indentasi. Merindukan masalah dengan lekukan multi! Memperbarui Jawaban. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSO
Heinrich Hartmann
2
Menggunakan xargscara ini tidak berguna, tidak efisien dan rusak (pikirkan nama file yang mengandung spasi atau kutipan). Mengapa Anda tidak menggunakan find's -execberalih bukan?
gniourf_gniourf
Saya berpendapat bahwa nama file dengan spasi dan tanda kutip rusak; ) Jika Anda perlu mendukung bahwa saya akan memilih: -print0opsi untuk menemukan / xargs. Saya suka xargs -execsejak: a) Pemisahan masalah b) dapat ditukar dengan GNU paralel lebih mudah.
Heinrich Hartmann
Diperbarui menambahkan komentar @gniourf_gniourf.
Heinrich Hartmann
4
Untuk mengonversi semua file Java secara rekursif dalam direktori menggunakan 4 spasi alih-alih tab:
Bagaimana jawaban ini berbeda dari ini yang diposting 4 tahun yang lalu?
PP
2
Begitu juga jawaban Anda. Sebenarnya, ini adalah versi yang lebih rendah dari jawaban Gene: 1) Jawaban Gene menjaga direktori dengan nama yang sama. 2) Tidak bergerak jika ekspansi gagal.
PP
4
Anda dapat menggunakan finddengan tabs-to-spacespaket untuk ini.
Pertama, instal tabs-to-spaces
npm install -g tabs-to-spaces
kemudian, jalankan perintah ini dari direktori root proyek Anda;
find .-name '*'-exec t2s --spaces 2{} \;
Ini akan mengganti setiap tabkarakter dengan 2 spacesdi setiap file.
Perintah yang sangat baik, tetapi berpotensi berbahaya dengan opsi rekursif dan semua file dalam folder seperti yang ditentukan di atas. Saya akan menambahkan opsi --dry-run "berjaga-jaga" untuk memastikan Anda duduk di folder yang tepat.
MortimerCat
2
Penggunaan expandseperti yang disarankan dalam jawaban lain tampaknya merupakan pendekatan yang paling logis untuk tugas ini saja.
Yang mengatakan, itu juga dapat dilakukan dengan Bash dan Awk jika Anda mungkin ingin melakukan beberapa modifikasi lain bersamanya.
Jika menggunakan Bash 4.0 atau lebih besar, shopt builtinglobstar dapat digunakan untuk mencari secara rekursif **.
Dengan GNU Awk versi 4.1 atau lebih tinggi, modifikasi file seperti "inplace" dapat dibuat:
Jelas, jumlah ruang yang diperlebar pada sebuah tab tergantung pada konteksnya. Dengan demikian, sed adalah alat yang sama sekali tidak pantas untuk tugas tersebut.
Sven
?? @ Bahkan, perintah sed saya melakukan hal yang sama dengan memperluas perintah ( expand -t 4 input >output)
Makah
3
Tentu saja tidak. expand -t 4akan memperluas tab a\tbke 3 spasi dan tab aa\tbke 2 spasi, seperti yang seharusnya. expandmempertimbangkan konteks tab, sedtidak dan akan mengganti tab dengan jumlah spasi yang Anda tentukan, terlepas dari konteksnya.
Sven
-1
Gunakan vim-way:
$ ex +'bufdo retab'-cxa **/*.*
Buat cadangan! sebelum menjalankan perintah di atas, karena dapat merusak file biner Anda.
Untuk menggunakan globstar( **) untuk rekursi, aktifkan oleh shopt -s globstar.
Untuk menentukan jenis file tertentu, gunakan misalnya: **/*.c.
Untuk memodifikasi tabstop, tambahkan +'set ts=2'.
... dan semua solusi Anda akan mengalahkan file-file biner dan sejenisnya (seperti file .png, file .pdf, dll.)
Martin Tournoij
Ini sejujurnya merupakan saran yang mengerikan untuk dokumentasi - seseorang harus akrab dengan sejumlah sintaks yang agak buram dan masalah semantik dari beberapa program untuk dapat memahami hal ini.
pr
adalah utilitas luar biasa untuk ini. Lihat jawaban ini .Jawaban:
find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +
File asli disimpan sebagai
[filename].orig
.Ganti '* .java' dengan akhiran file dari jenis file yang Anda cari. Dengan cara ini Anda dapat mencegah kerusakan file biner secara tidak sengaja.
Kerugian:
sumber
expand
.find ./ -type f -exec sed -i 's/^\t/####/g' {} \;
. Tapi saya tidak menyadari perintah memperluas - sangat berguna!Penggantian sederhana dengan
sed
tidak apa-apa tapi bukan solusi terbaik. Jika ada ruang "ekstra" di antara tab, mereka akan tetap ada setelah penggantian, sehingga margin akan menjadi acak-acakan. Tab yang diperluas di tengah garis juga tidak akan berfungsi dengan benar. Dibash
, kita bisa mengatakan sebaliknyauntuk diterapkan
expand
ke setiap file Java di pohon direktori saat ini. Hapus / ganti-name
argumen jika Anda menargetkan beberapa jenis file lainnya. Seperti yang disebutkan dalam salah satu komentar, berhati-hatilah saat mengeluarkan-name
atau menggunakan kartu pengganti yang lemah. Anda dapat dengan mudah menerima repositori dan file tersembunyi lainnya tanpa sengaja. Inilah sebabnya mengapa jawaban asli termasuk ini:sumber
{}
. Sepertinya dia tidak tahu$0
kapan-c
digunakan. Kemudian dimo414 berubah dari penggunaan temp saya di direktori konversi menjadi/tmp
, yang akan jauh lebih lambat jika/tmp
berada pada titik mount yang berbeda. Sayangnya saya tidak memiliki kotak Linux yang tersedia untuk menguji$0
proposal Anda . Tapi saya pikir Anda benar.find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
sponge
dari joeyh.name/code/moreutils , Anda dapat menulisfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
find . -name '*'
, saya baru saja menghancurkan git repo lokal sayaCoba alat baris perintah
expand
.dimana
-i
digunakan untuk memperluas hanya tab utama di setiap baris;-t 4
berarti bahwa setiap tab akan dikonversi menjadi 4 spasi spasi (8 secara default).sponge
berasal darimoreutils
paket, dan menghindari membersihkan file input .Akhirnya, Anda dapat menggunakan
gexpand
OSX, setelah menginstalcoreutils
dengan Homebrew (brew install coreutils
).sumber
-i
keexpand
hanya mengganti tab terkemuka di setiap baris. Ini membantu menghindari penggantian tab yang mungkin menjadi bagian dari kode.input
adalah file yang samaoutput
dengan bash clobbers konten bahkan sebelum memulaiexpand
. Beginilah cara>
kerjanya.Mengumpulkan komentar terbaik dari jawaban Gene , solusi terbaik sejauh ini, adalah dengan menggunakan
sponge
dari moreutils .Penjelasan:
./
secara rekursif mencari dari direktori saat ini-iname
adalah pencocokan huruf besar-kecil (untuk keduanya*.java
dan*.JAVA
suka)type -f
hanya menemukan file biasa (tidak ada direktori, binari atau symlink)-exec bash -c
menjalankan perintah berikut dalam subkulit untuk setiap nama file,{}
expand -t 4
perluas semua TAB menjadi 4 ruangsponge
menyerap input standar (dariexpand
) dan menulis ke file (yang sama) *.CATATAN : * Pengalihan file sederhana (
> "$0"
) tidak akan berfungsi di sini karena akan menimpa file terlalu cepat .Keuntungan : Semua izin file asli dipertahankan dan tidak ada
tmp
file perantara yang digunakan.sumber
Gunakan garis miring terbalik
sed
.Di linux:
Ganti semua tab dengan 1 tanda hubung di tempat, di semua file * .txt:
Ganti semua tab dengan 1 spasi di tempat, di semua file * .txt:
Ganti semua tab dengan 4 spasi di tempat, di semua file * .txt:
Di mac:
Ganti semua tab dengan 4 spasi di tempat, di semua file * .txt:
sumber
sed -i '' $'s/\t/ /g' $(find . -name "*.txt")
Anda dapat menggunakan
pr
perintah yang tersedia secara umum (halaman manual di sini ). Misalnya, untuk mengonversi tab menjadi empat spasi, lakukan ini:-t
menekan tajuk-e=num
perluas tab kenum
spasiUntuk mengonversi semua file di pohon direktori secara rekursif, sambil melewatkan file biner:
Logika untuk melewatkan file biner adalah dari posting ini .
CATATAN:
sumber
expand
mengingat bahwa keduanya POSIX? Misalnya apakah ada opsi perubahan sebaris? Git safety at: stackoverflow.com/a/52136507/895245Ini biasanya bukan yang Anda inginkan.
Apakah Anda ingin melakukan ini untuk gambar png? File PDF? Direktori .git? Anda
Makefile
(yang membutuhkan tab)? Dump SQL 5GB?Secara teori, Anda bisa meneruskan banyak opsi pengecualian ke
find
atau apa pun yang Anda gunakan; tetapi ini rapuh, dan akan pecah segera setelah Anda menambahkan file biner lainnya.Yang Anda inginkan, setidaknya:
expand
apakah ini,sed
tidak).Sejauh yang saya tahu, tidak ada utilitas Unix "standar" yang dapat melakukan ini, dan itu tidak mudah dilakukan dengan shell one-liner, jadi diperlukan skrip.
Beberapa waktu yang lalu saya membuat skrip kecil bernama sanitize_files yang melakukan hal itu. Juga perbaikan beberapa hal umum lainnya seperti mengganti
\r\n
dengan\n
, menambahkan Trailing\n
, dllAnda dapat menemukan skrip yang disederhanakan tanpa fitur tambahan dan argumen baris perintah di bawah ini, tetapi saya sarankan Anda menggunakan skrip di atas karena lebih mungkin untuk menerima perbaikan bug dan pembaruan lainnya daripada posting ini.
Saya juga ingin menunjukkan, dalam menanggapi beberapa jawaban lain di sini, bahwa menggunakan shell globbing bukanlah cara yang kuat untuk melakukan ini, karena cepat atau lambat Anda akan berakhir dengan lebih banyak file daripada yang akan cocok
ARG_MAX
(pada modern Sistem Linux 128k, yang mungkin tampak banyak, tetapi cepat atau lambat itu tidak cukup).sumber
Saya suka contoh "temukan" di atas untuk aplikasi rekursif. Untuk mengadaptasinya menjadi non-rekursif, hanya mengubah file di direktori saat ini yang cocok dengan wildcard, ekspansi glob shell bisa mencukupi untuk sejumlah kecil file:
Jika Anda ingin itu diam setelah Anda percaya bahwa itu berfungsi, cukup letakkan
-v
padash
perintah di akhir.Tentu saja Anda dapat memilih set file dalam perintah pertama. Misalnya, daftar hanya subdirektori tertentu (atau direktori) dengan cara yang terkontrol seperti ini:
Atau pada gilirannya jalankan temukan (1) dengan beberapa kombinasi parameter kedalaman dll:
sumber
ARG_MAX
panjang. Ini 128k pada sistem Linux, tetapi saya telah menemui batas ini cukup kali untuk tidak bergantung pada shell globbing.find
dapat dikatakan-maxdepth 1
, dan hanya memproses entri direktori yang sedang dimodifikasi, bukan seluruh pohon.Saya digunakan
astyle
untuk indentasi ulang semua kode C / C ++ saya setelah menemukan tab dan spasi campuran. Ia juga memiliki opsi untuk memaksa gaya penyangga tertentu jika Anda mau.sumber
Satu dapat digunakan
vim
untuk itu:Seperti yang dinyatakan oleh Carpetsmoker, itu akan melakukan retab sesuai dengan
vim
pengaturan Anda . Dan modelines dalam file, jika ada. Juga, itu akan mengganti tab tidak hanya di awal baris. Yang bukan apa yang biasanya Anda inginkan. Misalnya, Anda mungkin memiliki literal, yang berisi tab.sumber
:retab
akan mengubah semua tab dalam file, bukan yang di awal. itu juga tergantung pada apa:tabstop
dan:expandtab
pengaturan Anda di vimrc atau modeline, jadi ini mungkin tidak berfungsi sama sekali.tabstop
danexpandtab
, itu akan berhasil jika Anda menggunakanvim
. Kecuali jika Anda memiliki garis mode di file.Rekomendasi saya adalah menggunakan:
Komentar:
sed
adalah editor aliran. Gunakanex
untuk mengedit di tempat. Ini menghindari membuat file temp tambahan dan spawning shells untuk setiap penggantian seperti pada jawaban teratas .find|xargs
sebagai gantifind -exec
. Seperti yang ditunjukkan oleh @ gniourf-gniourf ini menyebabkan masalah dengan spasi, tanda kutip dan karakter kontrol dalam nama file cf. Wheeler .sumber
ex
mungkin tidak tersedia di setiap sistem Unix. Mengganti denganvi -e
mungkin bekerja pada lebih banyak mesin. Juga, regex Anda menggantikan sejumlah karakter tab awal dengan dua spasi. Ganti regex dengan+%s/\t/ /g
tidak merusak lekukan multi level. Namun ini juga memengaruhi karakter tab yang tidak digunakan untuk indentasi./\t/ /
varian pada file saya, tetapi memilih untuk/\t\+//
tidak merusak tab yang tidak membuat indentasi. Merindukan masalah dengan lekukan multi! Memperbarui Jawaban. [1] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSOxargs
cara ini tidak berguna, tidak efisien dan rusak (pikirkan nama file yang mengandung spasi atau kutipan). Mengapa Anda tidak menggunakanfind
's-exec
beralih bukan?-print0
opsi untuk menemukan / xargs. Saya suka xargs-exec
sejak: a) Pemisahan masalah b) dapat ditukar dengan GNU paralel lebih mudah.Untuk mengonversi semua file Java secara rekursif dalam direktori menggunakan 4 spasi alih-alih tab:
sumber
Anda dapat menggunakan
find
dengantabs-to-spaces
paket untuk ini.Pertama, instal
tabs-to-spaces
kemudian, jalankan perintah ini dari direktori root proyek Anda;
Ini akan mengganti setiap
tab
karakter dengan 2spaces
di setiap file.sumber
Tidak ada badan yang disebutkan
rpl
? Menggunakan rpl Anda dapat mengganti string apa pun. Untuk mengonversi tab menjadi spasi,sangat sederhana.
sumber
Penggunaan
expand
seperti yang disarankan dalam jawaban lain tampaknya merupakan pendekatan yang paling logis untuk tugas ini saja.Yang mengatakan, itu juga dapat dilakukan dengan Bash dan Awk jika Anda mungkin ingin melakukan beberapa modifikasi lain bersamanya.
Jika menggunakan Bash 4.0 atau lebih besar, shopt builtin
globstar
dapat digunakan untuk mencari secara rekursif**
.Dengan GNU Awk versi 4.1 atau lebih tinggi, modifikasi file seperti "inplace" dapat dibuat:
Jika Anda ingin mengatur jumlah spasi per tab:
sumber
Unduh dan jalankan skrip berikut untuk secara rekursif mengonversi tab keras menjadi tab lunak dalam file teks biasa.
Jalankan skrip dari dalam folder yang berisi file teks biasa.
sumber
Metode ramah repositori
Bertindak pada semua file di bawah direktori saat ini:
Bertindak hanya pada file C atau C ++:
Anda mungkin menginginkan ini terutama karena Makefile yang mengganggu yang memerlukan tab.
Perintah
git grep --cached -Il ''
:.git
seperti yang dijelaskan di: Bagaimana cara mendaftar semua file teks (non-biner) dalam repositori git?
chmod --reference
membuat izin file tidak berubah: /unix/20645/clone-ownership-and-permissions-from-another-file Sayangnya saya tidak dapat menemukan alternatif POSIX yang ringkas .Jika basis kode Anda memiliki ide gila untuk mengizinkan tab mentah fungsional dalam string, gunakan:
dan kemudian bersenang-senang memeriksa semua tab awal yang tidak dimulai satu per satu, yang dapat Anda daftarkan: Apakah mungkin untuk mendapatkan grep untuk tab?
Diuji pada Ubuntu 18.04.
sumber
Mengonversi tab menjadi spasi hanya dalam file ".lua" [tab -> 2 spasi]
sumber
expand -t 4 input >output
)expand -t 4
akan memperluas taba\tb
ke 3 spasi dan tabaa\tb
ke 2 spasi, seperti yang seharusnya.expand
mempertimbangkan konteks tab,sed
tidak dan akan mengganti tab dengan jumlah spasi yang Anda tentukan, terlepas dari konteksnya.Gunakan vim-way:
globstar
(**
) untuk rekursi, aktifkan olehshopt -s globstar
.**/*.c
.Untuk memodifikasi tabstop, tambahkan
+'set ts=2'
.Namun sisi buruknya adalah ia dapat mengganti tab di dalam string .
Jadi untuk solusi yang sedikit lebih baik (dengan menggunakan substitusi), coba:
Atau dengan menggunakan
ex
editor +expand
utility:Untuk spasi tambahan, lihat: Bagaimana menghapus spasi spasi tambahan untuk banyak file?
Anda dapat menambahkan fungsi berikut ke
.bash_profile
:sumber
:retab
mungkin tidak bekerja sama sekali , shell globbing adalah solusi yang buruk untuk hal semacam ini , Anda:s
perintah akan menggantikan setiap jumlah tab dengan 2 spasi (yang Anda hampir tidak pernah mau), memulai ex hanya untuk menjalankan suatu:!expand
proses itu konyol ...