मैं निर्देशिका की हर फ़ाइल में टैब को रिक्त स्थान में कैसे बदल सकता हूं?


251

मैं किसी निर्देशिका की प्रत्येक फ़ाइल में संभवतः रिक्त स्थान को टैब में कैसे बदल सकता हूं (संभवतः पुनरावर्ती)?

इसके अलावा, प्रति टैब रिक्त स्थान की संख्या निर्धारित करने का एक तरीका है?


आप फ़ाइल या फ़ाइल नाम में टैब बदलना चाहते हैं?
cppcoder

3
prइसके लिए एक अद्भुत उपयोगिता है। इस जवाब को देखें ।
कोडफ़ेस्टर

जवाबों:


69

चेतावनी: यह आपके रेपो को तोड़ देगा।

यह भ्रष्ट द्विआधारी फ़ाइलें उन तहत सहित svn, .git! उपयोग करने से पहले टिप्पणी पढ़ें!

find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +

मूल फ़ाइल के रूप में सहेजा गया है [filename].orig

उस फ़ाइल प्रकार के फ़ाइल अंत के साथ '* .java' को बदलें, जिसे आप खोज रहे हैं। इस तरह आप बाइनरी फ़ाइलों के आकस्मिक भ्रष्टाचार को रोक सकते हैं।

downsides:

  • एक फ़ाइल में हर जगह टैब बदल देगा।
  • यदि आपको इस निर्देशिका में 5GB SQL डंप होने में लंबा समय लगेगा।

12
दृश्य स्थान के लिए जो टैब और रिक्त स्थान का मिश्रण है, यह दृष्टिकोण गलत विस्तार देता है।
पिज़्ज़ा

7
मैं केवल उदाहरण के लिए एक फ़ाइल मिलानकर्ता जोड़ना चाहूँगा। केवल .php फ़ाइलों को खोजने के लिए। / -iname "* .php" -type f -exec sed -i 's / \ t / g / {{} \;
डैनियल लुका क्लीनयूनिकॉर्न

98
उपयोग नहीं किया! यदि किसी स्ट्रिंग में एक एम्बेडेड टैब है, तो आप अपने कोड को समाप्त कर सकते हैं। यह वही है जो विस्तार कमांड को संभालने के लिए था। का उपयोग करें expand
डेविड डब्ल्यू।

5
@DavidW। मैं इस कमांड को केवल लाइन की शुरुआत से टैब को बदलने के लिए अपडेट करूंगा। find ./ -type f -exec sed -i 's/^\t/####/g' {} \;। लेकिन मुझे विस्तृत कमांड की जानकारी नहीं थी - बहुत उपयोगी!
मार्टिन कोन्सेनी

29
प्रयोग नहीं करें! इस उत्तर ने भी मेरे स्थानीय गिट रिपॉजिटरी को बर्बाद कर दिया। यदि आपके पास मिश्रित टैब और रिक्त स्थान वाली फाइलें हैं, तो यह # के अनुक्रमों को सम्मिलित करेगा। इसके बजाय जीन द्वारा जवाब या डोगे द्वारा टिप्पणी का उपयोग करें।
कठपुतली

344

के साथ सरल प्रतिस्थापन sedठीक है लेकिन सबसे अच्छा संभव समाधान नहीं है। यदि टैब के बीच "अतिरिक्त" स्थान हैं, तो वे प्रतिस्थापन के बाद भी वहां रहेंगे, इसलिए हाशिये पर रैगिंग होगी। लाइनों के बीच में विस्तारित टैब भी सही ढंग से काम नहीं करेगा। में bash, हम इसके बजाय कह सकते हैं

find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

expandवर्तमान निर्देशिका ट्री में प्रत्येक जावा फ़ाइल पर लागू करने के लिए। -nameयदि आप कुछ अन्य फ़ाइल प्रकारों को लक्षित कर रहे हैं, तो तर्क को निकालें / बदलें । टिप्पणियों में से एक के रूप में, -nameकमजोर, वाइल्डकार्ड को हटाते या उपयोग करते समय बहुत सावधान रहें । आप आसानी से बिना इरादे के भंडार और अन्य छिपी हुई फाइलों को आसानी से देख सकते हैं। यही कारण है कि मूल उत्तर में यह शामिल है:

हमेशा कुछ गलत होने की स्थिति में इस तरह की कोशिश करने से पहले आपको पेड़ की एक बैकअप प्रतिलिपि बनानी चाहिए।


2
@JeffreyMartinez बढ़िया सवाल। gniourf_gniourf ने 11 नवंबर को मेरे मूल उत्तर को संपादित किया और उपयोग करने के उचित तरीके को नहीं जानने के बारे में अपमानजनक टिप्पणी की {}। ऐसा लगता है कि $0जब -cवह इस्तेमाल किया जाता है तो उसके बारे में नहीं पता था । तब dimo414 रूपांतरण निर्देशिका में एक अस्थायी के मेरे उपयोग से बदल गया /tmp, जो कि /tmpएक अलग माउंट बिंदु पर होने पर बहुत धीमी हो जाएगी । दुर्भाग्य से मेरे पास आपके $0प्रस्ताव का परीक्षण करने के लिए लिनक्स बॉक्स उपलब्ध नहीं है । लेकिन मुझे लगता है कि आप सही हैं।
जीन

1
@ जीईएन, स्पष्टीकरण के लिए धन्यवाद, जो स्टैकओवरफ्लो की तरह लगता है ठीक है: पी। हालाँकि, मैं इसके साथ हूँ, लेकिन मैं जोड़ता हूँ कि मुझे * .java के उद्धरणों का उपयोग * .java के उचित रूप से बचने के लिए करना होगा।
जेफरी मार्टिनेज

2
अगर किसी को भी 'अज्ञात प्राथमिक या ऑपरेटर' की त्रुटि हो रही है, तो यहां पूरी कमांड है, जो इसे ठीक करेगा:find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
डोगे

4
मुझे लगा कि यह उत्तर पर्याप्त टिप्पणियों के रूप में नहीं था जैसा कि यह था, इसलिए यह मेरा है: यदि joeyh.name/code/moreutilssponge से उपयोग किया जाता है , तो आप लिख सकते हैंfind . -name '*.py' ! -type d -exec bash -c 'expand -t 8 "$0" | sponge "$0"' {} \;
tokland

8
मूर्ख मत बनो और प्रयोग करो find . -name '*', मैंने अभी-अभी अपने स्थानीय गिट रेपो को नष्ट किया
गौतम

193

कमांड लाइन टूल आज़माएं expand

expand -i -t 4 input | sponge output

कहाँ पे

  • -i प्रत्येक पंक्ति पर केवल प्रमुख टैब का विस्तार करने के लिए उपयोग किया जाता है;
  • -t 4 इसका मतलब है कि प्रत्येक टैब को 4 व्हाट्सएप चार्ट (डिफ़ॉल्ट रूप से 8) में बदल दिया जाएगा।
  • spongeसे है moreutilsपैकेज, और टाल इनपुट फ़ाइल समाशोधन

अंत में, आप Homebrew ( ) के साथ gexpandस्थापित करने के बाद, OSX पर उपयोग कर सकते हैं ।coreutilsbrew install coreutils


5
यह में से एक GNU_Core_Utilities
कीव

32
आप पास करना चाहिए -iकरने के लिए expandप्रत्येक पंक्ति में केवल प्रमुख टैब को बदलने के लिए। यह उन टैब को बदलने से बचने में मदद करता है जो कोड का हिस्सा हो सकते हैं।
क्वोलोन प्रश्न

10
कैसे एक निर्देशिका में हर एक फ़ाइल के बारे में पुनरावर्ती?
अहानिबेक्स्ड

4
हर बार जब मैं इसका उपयोग करने की कोशिश करता हूं तो यह फाइलों के कुछ (आमतौर पर सभी) रिक्त करता है। : \
ThorSummoner

5
@ थोरसुमोनर: अगर बैश inputके समान ही फाइल है outputतो कंटेंट को शुरू करने से पहले भी expand। इस तरह >काम करता है।
राबर्ट सीमर

34

से सबसे अच्छा टिप्पणी एकत्रित जीन का जवाब , अब तक का सबसे अच्छा समाधान, का उपयोग करना है spongeसे moreutils

sudo apt-get install moreutils
# The complete one-liner:
find ./ -iname '*.java' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' {} \;

स्पष्टीकरण:

  • ./ वर्तमान निर्देशिका से पुनरावर्ती खोज कर रहा है
  • -inameएक मामला असंवेदनशील मैच है (दोनों *.javaऔर *.JAVAपसंद के लिए)
  • type -f केवल नियमित फ़ाइलें (कोई निर्देशिका, बायनेरी या सिमिलिंक) नहीं मिलती
  • -exec bash -c प्रत्येक फ़ाइल के नाम के लिए एक उपधारा में आदेशों का पालन करें, {}
  • expand -t 4 सभी TAB को 4 स्थानों तक फैलता है
  • spongeमानक इनपुट (से expand) को भिगोएँ और एक फ़ाइल (उसी एक) पर लिखें *।

नोट : * एक साधारण फ़ाइल पुनर्निर्देशन ( > "$0") यहाँ काम नहीं करेगा क्योंकि यह बहुत जल्द फ़ाइल को अधिलेखित कर देगा

लाभ : सभी मूल फ़ाइल अनुमतियां बरकरार रखी जाती हैं और कोई मध्यवर्ती tmpफ़ाइलें उपयोग नहीं की जाती हैं।


2
TIL: अद्भुत स्पॉन्ज कमांड, लिनक्स के उपयोग के 15 साल बाद। इंटरनेट से रहस्यमय शूरवीर धन्यवाद।
sscarduzio

19

बैकस्लैश-बच का उपयोग करें sed

लिनक्स पर:

  • सभी टैब को 1 हाइफ़न इनलाइन के साथ बदलें, सभी * .txt फ़ाइलों में:

    sed -i $'s/\t/-/g' *.txt
  • सभी टैब को 1 *। Inxt फ़ाइलों के साथ बदलें।

    sed -i $'s/\t/ /g' *.txt
  • सभी टैब को 4 रिक्त स्थान के साथ बदलें, सभी * .txt फ़ाइलों में:

    sed -i $'s/\t/    /g' *.txt

एक मैक पर:

  • सभी टैब को 4 रिक्त स्थान के साथ बदलें, सभी * .txt फ़ाइलों में:

    sed -i '' $'s/\t/    /g' *.txt

2
@ Машаsed -i '' $'s/\t/ /g' $(find . -name "*.txt")
xyzale

यह उत्तर सबसे सरल प्रतीत होता है।
यान किंग यिन

6

आप आम तौर पर उपलब्ध prकमांड ( यहां मैन पेज ) का उपयोग कर सकते हैं । उदाहरण के लिए, टैब को चार स्थानों में बदलने के लिए, यह करें:

pr -t -e=4 file > file.expanded
  • -t शीर्षकों को दबाता है
  • -e=numnumरिक्त स्थान के लिए टैब का विस्तार करता है

बाइनरी फ़ाइलों को लंघन करते हुए, एक निर्देशिका ट्री में सभी फ़ाइलों को पुनरावर्ती रूप से परिवर्तित करने के लिए:

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

बाइनरी फ़ाइलों को स्किप करने का तर्क इस पोस्ट से है

ध्यान दें:

  1. ऐसा करना एक git या svn रेपो में खतरनाक हो सकता है
  2. यह सही समाधान नहीं है यदि आपके पास कोड फाइलें हैं जिनमें स्ट्रिंग स्ट्रिंग शाब्दिक रूप से टैब हैं

1
किसी भी तरह का फायदा यह हुआ expandकि दोनों पोसिक्स हैं? जैसे इसमें एक इनलाइन परिवर्तन विकल्प है? Git सुरक्षा पर: stackoverflow.com/a/52136507/895245
Ciro Santilli 病 stack stack stack

5

मैं किसी निर्देशिका की प्रत्येक फ़ाइल में संभवतः रिक्त स्थान को टैब में कैसे बदल सकता हूं (संभवतः पुनरावर्ती)?

यह आमतौर पर वह नहीं है जो आप चाहते हैं।

क्या आप png छवियों के लिए ऐसा करना चाहते हैं? पीडीएफ फाइलें? .गित निर्देशिका आपका Makefile(जिसे टैब की आवश्यकता है )? 5GB SQL डंप?

आप, सिद्धांत रूप में, findया जो कुछ भी आप उपयोग कर रहे हैं , उसे पूरी तरह से बाहर कर सकते हैं; लेकिन यह नाजुक है, और जैसे ही आप अन्य बाइनरी फाइल जोड़ते हैं, वैसे ही टूट जाएगा।

आप जो चाहते हैं, वह कम से कम है:

  1. फ़ाइलों को एक निश्चित आकार पर छोड़ दें।
  2. पता लगाएँ कि क्या कोई फाइल NULL बाइट की मौजूदगी की जाँच करके बाइनरी है।
  3. केवल फ़ाइल की शुरुआत में टैब को बदलें ( expandयह sed ऐसा नहीं करता है)।

जहां तक ​​मुझे पता है, कोई "मानक" यूनिक्स उपयोगिता नहीं है जो ऐसा कर सकती है, और यह शेल वन-लाइनर के साथ करना बहुत आसान नहीं है, इसलिए एक स्क्रिप्ट की आवश्यकता है।

कुछ समय पहले मैंने sanitize_files नाम से एक छोटी स्क्रिप्ट बनाई थी जो वास्तव में ऐसा ही करती है। यह भी जगह जैसे कुछ अन्य आम सामान को ठीक करता \r\nसाथ \n, पीछे जोड़ने \nआदि,

आप नीचे दी गई अतिरिक्त सुविधाओं और कमांड-लाइन तर्कों के बिना एक सरलीकृत स्क्रिप्ट पा सकते हैं , लेकिन मैं आपको उपरोक्त स्क्रिप्ट का उपयोग करने की सलाह देता हूं क्योंकि इस पोस्ट की तुलना में बगफिक्स और अन्य अपडेट प्राप्त होने की अधिक संभावना है।

मैं यहां कुछ अन्य जवाबों के जवाब में यह भी कहना चाहूंगा कि शेल ग्लोबिंग का उपयोग करना ऐसा करने का एक मजबूत तरीका नहीं है, क्योंकि जितनी जल्दी या बाद में आप अधिक फाइलों के साथ समाप्त हो जाएंगे, ARG_MAXआधुनिक रूप में फिट होंगे लिनक्स सिस्टम यह 128k है, जो बहुत कुछ लग सकता है, लेकिन जितनी जल्दी या बाद में यह पर्याप्त नहीं है)।


#!/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:
            return True
    return False


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))
            continue

        if size == 0: continue
        if 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))
            continue

        if is_binary(data):
            print("Skipping `%s' because it looks binary" % f)
            continue

        data = data.split(b'\n')

        fixed_indent = False
        for i, line in enumerate(data):
            # Fix indentation
            repl_count = 0
            while 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)

गिट के भीतर, बाइनरी चेक आसान है: stackoverflow.com/a/52136507/895245
Ciro Santilli Sant binary binary binary

5

मैं पुनरावर्ती आवेदन के लिए ऊपर "खोज" उदाहरण को पसंद करता हूं। इसे गैर-पुनरावर्ती होने के लिए अनुकूलित करने के लिए, केवल वर्तमान निर्देशिका में फ़ाइलों को बदलना जो वाइल्डकार्ड से मेल खाते हैं, शेल ग्लोब विस्तार कम मात्रा में फ़ाइलों के लिए पर्याप्त हो सकता है:

ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh -v

यदि आप चाहते हैं कि यह भरोसा करने के बाद कि यह काम करता है, तो अंत -vमें shकमांड पर ड्रॉप करें ।

बेशक आप पहले कमांड में फ़ाइलों के किसी भी सेट को चुन सकते हैं। उदाहरण के लिए, इस तरह नियंत्रित तरीके से केवल एक विशेष उपनिर्देशिका (या निर्देशिका) को सूचीबद्ध करें:

ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

या गहराई में मापदंडों आदि के कुछ संयोजन के साथ बदले में खोजें (1):

find mod/ -name '*.php' -mindepth 1 -maxdepth 2 | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

1
शेल ग्लोबिंग जल्द या बाद में टूट जाएगा, क्योंकि फ़ाइल नाम की कुल मात्रा केवल ARG_MAXलंबाई की हो सकती है । लिनक्स सिस्टम पर यह 128k है, लेकिन शेल ग्लोबिंग पर भरोसा न करने के लिए मैंने इस सीमा का पर्याप्त बार सामना किया है।
मार्टिन टूरनोइज

1
आपको वास्तव में उन्हें अनुकूलित करने की आवश्यकता नहीं है। findबताया जा सकता है -maxdepth 1, और यह केवल निर्देशिका की प्रविष्टियों को संशोधित करता है, न कि पूरे पेड़ को।
शैडो रेंजर

4

मैं astyleमिश्रित टैब और रिक्त स्थान खोजने के बाद अपने सभी C / C ++ कोड को फिर से इंडेंट करता था। यदि आप चाहें तो किसी विशेष ब्रेस स्टाइल को मजबूर करने के भी विकल्प हैं।


4

एक vimउस के लिए उपयोग कर सकते हैं :

find -type f \( -name '*.css' -o -name '*.html' -o -name '*.js' -o -name '*.php' \) -execdir vim -c retab -c wq {} \;

जैसा कि Carpetsmoker ने कहा है, यह आपकी vimसेटिंग्स के अनुसार रिटाब करेगा । और फाइलों में मॉडलिंग, यदि कोई हो। इसके अलावा, यह न केवल लाइनों की शुरुआत में टैब की जगह लेगा। जो आप आमतौर पर नहीं चाहते हैं। उदाहरण के लिए, आपके पास शाब्दिक हो सकते हैं, जिसमें टैब होते हैं।


:retabएक फ़ाइल में सभी टैब को बदल देगा, न कि शुरुआत में। यह इस बात पर भी निर्भर करता है कि आपका :tabstopऔर :expandtabसेटिंग्स vimrc या modeline में क्या है, इसलिए यह बिल्कुल काम नहीं कर सकता है।
मार्टिन टूरनोइज

@Carpetsmoker लाइनों की शुरुआत में टैब के बारे में अच्छी बात है। क्या यहां कोई भी समाधान इस मामले को संभालता है? के रूप में tabstopऔर expandtabसेटिंग्स के लिए, यह काम करेगा अगर आप उपयोग कर रहे हैं vim। जब तक आपके पास फ़ाइलों में मोड लाइनें नहीं हैं।
x-yuri

@ एक्स-यूरी अच्छा सवाल है, लेकिन आम तौर पर लूट। अधिकांश लोग शाब्दिक रूप से वास्तविक टैब का उपयोग नहीं करते हैं।
रिकार्डो क्रूज़

4

मेरी सिफारिश का उपयोग करने के लिए है:

find . -name '*.lua' -exec ex '+%s/\t/  /g' -cwq {} \;

टिप्पणियाँ:

  1. जगह संपादन में उपयोग करें। VCS में बैकअप रखें। * .Orig फ़ाइलों का उत्पादन करने की आवश्यकता नहीं है। किसी भी मामले में यह सुनिश्चित करने के लिए अपने अंतिम प्रतिबद्ध के खिलाफ परिणाम को फैलाने के लिए यह अच्छा है कि यह अपेक्षित रूप से काम करे।
  2. sedएक धारा संपादक है। exजगह संपादन के लिए उपयोग करें । यह प्रत्येक अस्थायी और अतिरिक्त जवाब के रूप में प्रतिस्थापन के लिए अतिरिक्त अस्थायी फ़ाइलों और spawning गोले बनाने से बचा जाता है ।
  3. चेतावनी: यह सभी टैब के साथ खिलवाड़ करता है, न केवल इंडेंटेशन के लिए उपयोग किया जाता है। इसके अलावा यह टैब के संदर्भ में जागरूक प्रतिस्थापन नहीं करता है। यह मेरे उपयोग के मामले के लिए पर्याप्त था। लेकिन आपके लिए स्वीकार्य नहीं हो सकता है।
  4. EDIT: इस उत्तर का एक पुराना संस्करण जिसका उपयोग किया find|xargsगया था find -exec। जैसा कि @ gniourf-gniourf ने बताया है कि यह फ़ाइल नाम cf. में रिक्त स्थान, उद्धरण और नियंत्रण चार्ट के साथ समस्याओं की ओर जाता है। व्हीलर

exहर यूनिक्स प्रणाली पर उपलब्ध नहीं हो सकता है। इसे vi -eअधिक मशीनों पर काम करने के साथ प्रतिस्थापित किया जा सकता है। साथ ही, आपका रेगेक्स दो स्थानों के साथ टैब वर्णों को शुरू करने की किसी भी संख्या को बदल देता है। +%s/\t/ /gमल्टी लेवल इंडेंटेशन को नष्ट नहीं करने के साथ रेगेक्स को बदलें । हालाँकि यह उन टैब वर्णों को भी प्रभावित करता है जिनका उपयोग इंडेंटेशन के लिए नहीं किया जाता है।
लुकास श्मेलिसेन

पूर्व POSIX का हिस्सा है [1] इसलिए उपलब्ध होना चाहिए। मल्टी लेवल इंडेंडेशन के बारे में अच्छी बात। मैंने वास्तव में /\t/ /अपनी फ़ाइलों पर संस्करण का उपयोग किया था , लेकिन /\t\+//गैर-इंडेंटिंग टैब को नहीं तोड़ने का विकल्प चुना । बहु-इंडेंटेशन के साथ मुद्दों को याद किया! उत्तर को अद्यतन करना। [१] man7.org/linux/man-pages/man1/ex.1p.html#SEE%C2%A0ALSO
हेनरिक हार्टमैन

2
xargsइस तरह से उपयोग करना बेकार, अक्षम और टूटा हुआ है (रिक्त स्थान या उद्धरण वाले फ़ाइलनाम के बारे में सोचें)। क्यों आप का उपयोग नहीं करते findके -execस्विच के बजाय?
ग्नौरफ_ग्निउरफ

मेरा तर्क है कि रिक्त स्थान और उद्धरण के साथ फ़ाइल नाम टूट गए हैं; ) यदि आपको समर्थन करने की आवश्यकता है तो मैं इसका -print0विकल्प चुनूंगा : खोजने के लिए विकल्प / xargs। मैं xargs को अधिक पसंद करता हूं -exec: a) चिंताओं का पृथक्करण b) इसे GNU के समानांतर स्वैप किया जा सकता है।
हेनरिक हार्टमैन

@Gniourf_gniourf टिप्पणियों को अपडेट करने के लिए अपडेट किया गया।
हेनरिक हार्टमैन

4

टैब के बजाय 4 रिक्त स्थान का उपयोग करने के लिए निर्देशिका में सभी जावा फ़ाइलों को पुन: रूपांतरित करने के लिए:

find . -type f -name *.java -exec bash -c 'expand -t 4 {} > /tmp/stuff;mv /tmp/stuff {}' \;

कैसे से इस सवाल का जवाब अलग है यह 4 साल पहले पोस्ट किया गया था जो?
पीपी

2
तो आपका जवाब है वास्तव में, यह जीन के उत्तर का एक अवर संस्करण है: 1) जीन का जवाब एक ही नाम के साथ निर्देशिकाओं का ध्यान रखता है। 2) अगर विस्तार नहीं हुआ तो यह आगे नहीं बढ़ता
पीपी

4

आप इसके लिए पैकेज के findसाथ उपयोग कर सकते हैं tabs-to-spaces

सबसे पहले, स्थापित करें tabs-to-spaces

npm install -g tabs-to-spaces

फिर, इस कमांड को अपने प्रोजेक्ट के रूट डायरेक्टरी से चलाएं;

find . -name '*' -exec t2s --spaces 2 {} \;

यह हर फ़ाइल में प्रत्येक tabवर्ण को 2 से बदल देगा spaces


3

किसी निकाय का उल्लेख नहीं है rpl? Rpl का उपयोग करके आप किसी भी स्ट्रिंग को बदल सकते हैं। टैब को रिक्त स्थान में बदलने के लिए,

rpl -R -e "\t" "    "  .

बहुत आसान।


1
इसने मेरे रेपो में सभी बाइनरी फाइलों को दूषित कर दिया।
आरोन फ्रेंके

1
एक उत्कृष्ट कमांड, लेकिन उपरोक्त के रूप में फ़ोल्डर विकल्प में पुनरावर्ती और सभी फ़ाइलों के साथ संभावित रूप से खतरनाक है। मैं --dry- रन विकल्प "सिर्फ मामले में" जोड़ना सुनिश्चित करने के लिए कि आप सही फ़ोल्डर में बैठे हैं।
मोर्टिमरकैट

2

expandअन्य उत्तरों में सुझाए अनुसार उपयोग इस कार्य के लिए सबसे तार्किक दृष्टिकोण है।

यह कहा गया है, यह बैश और ऑक के साथ भी किया जा सकता है यदि आप इसके साथ कुछ अन्य संशोधन करना चाहते हैं।

यदि बैश 4.0 या अधिक का उपयोग कर रहे हैं, तो शॉप्ट बिल्ड globstar का उपयोग पुनरावर्ती रूप से खोजने के लिए किया जा सकता है **

GNU Awk संस्करण 4.1 या उससे अधिक के साथ, "inplace" फ़ाइल संशोधन की तरह सेड बनाया जा सकता है:

shopt -s globstar
gawk -i inplace '{gsub("\t","    ")}1' **/*.ext

यदि आप प्रति टैब रिक्त स्थान की संख्या सेट करना चाहते हैं:

gawk -i inplace -v n=4 'BEGIN{for(i=1;i<=n;i++) c=c" "}{gsub("\t",c)}1' **/*.ext

2

निम्न स्क्रिप्ट को पुन: डाउनलोड करें और हार्ड टैब्स को सादे टेक्स्ट फ़ाइलों में सॉफ्ट टैब में बदलने के लिए चलाएं।

फ़ोल्डर के अंदर से स्क्रिप्ट को निष्पादित करें जिसमें सादा पाठ फ़ाइलें हैं।

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(expand --initial -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;

2

गिट रिपॉजिटरी फ्रेंडली तरीका

git-tab-to-space() (
  d="$(mktemp -d)"
  git grep --cached -Il '' | grep -E "${1:-.}" | \
    xargs -I'{}' bash -c '\
    f="${1}/f" \
    && expand -t 4 "$0" > "$f" && \
    chmod --reference="$0" "$f" && \
    mv "$f" "$0"' \
    '{}' "$d" \
  ;
  rmdir "$d"
)

वर्तमान निर्देशिका के अंतर्गत सभी फाइलों पर अधिनियम:

git-tab-to-space

केवल C या C ++ फ़ाइलों पर कार्य करें:

git-tab-to-space '\.(c|h)(|pp)$'

आप संभवतः उन कष्टप्रद मेकफाइल्स के कारण इसे विशेष रूप से चाहते हैं जिन्हें टैब की आवश्यकता होती है।

आदेश git grep --cached -Il '':

  • केवल ट्रैक की गई फ़ाइलों को सूचीबद्ध करता है, इसलिए अंदर कुछ भी नहीं .git
  • निर्देशिकाओं को निकालता है, बाइनरी फ़ाइलें (दूषित हो जाएगा), और सीमलिंक (नियमित फ़ाइलों में परिवर्तित हो जाएगा)

जैसा कि समझाया गया है: गिट रिपॉजिटरी में सभी पाठ (गैर-बाइनरी) फ़ाइलों को कैसे सूचीबद्ध करें?

chmod --referenceफ़ाइल अनुमतियों को अपरिवर्तित रखता है: /unix/20645/clone-ownership-and-permissions-from-another-file दुर्भाग्य से मुझे एक रसीला पॉज़्टरनेट विकल्प नहीं मिल सकता है

यदि आपके कोडबेस के पास स्ट्रिंग्स में कार्यात्मक कच्चे टैब की अनुमति देने के लिए पागल विचार था, तो उपयोग करें:

expand -i

और फिर एक-एक करके लाइन टैब के सभी नॉन स्टार्ट पर जाने का मज़ा लें, जिसे आप लिस्ट कर सकते हैं: क्या टैब के लिए grep git करना संभव है?

उबंटू 18.04 पर परीक्षण किया गया।


-1

".Lua" फाइलों में टैब को अंतरिक्ष में बदलना [टैब -> 2 स्पेस]

find . -iname "*.lua" -exec sed -i "s#\t#  #g" '{}' \;

जाहिर है, एक टैब का विस्तार करने वाली जगह की मात्रा संदर्भ पर निर्भर करती है। इस प्रकार, sed कार्य के लिए पूरी तरह से अनुचित उपकरण है।
स्वेन

?? @ मेरे आदेश, मेरी sed कमांड वही काम करती है जो कमांड का विस्तार करती है ( expand -t 4 input >output)
Makah

3
बिलकूल नही। expand -t 4टैब a\tbको 3 स्थानों में और टैब aa\tbको 2 स्थानों में विस्तारित करेगा , जैसा कि यह होना चाहिए। expandएक टैब के संदर्भ को ध्यान में रखता है, टैब को sedप्रतिस्थापित नहीं करेगा और आपके निर्दिष्ट स्थान की मात्रा के साथ संदर्भ की परवाह किए बिना।
स्वेन

-1

वीम-वे का उपयोग करें:

$ ex +'bufdo retab' -cxa **/*.*
  • बैकअप बनाओ! उपरोक्त कमांड निष्पादित करने से पहले, क्योंकि यह आपकी बाइनरी फ़ाइलों को भ्रष्ट कर सकता है।
  • उपयोग करने के लिए globstar( **) पुनरावर्तन के लिए, द्वारा सक्रिय करें shopt -s globstar
  • विशिष्ट फ़ाइल प्रकार निर्दिष्ट करने के लिए, उदाहरण के लिए उपयोग करें **/*.c:।

टैबस्टॉप को संशोधित करने के लिए, जोड़ें +'set ts=2'

हालांकि डाउन-साइड यह है कि यह स्ट्रिंग्स के अंदर टैब को बदल सकता है ।

तो थोड़ा बेहतर समाधान के लिए (प्रतिस्थापन का उपयोग करके), कोशिश करें:

$ ex -s +'bufdo %s/^\t\+/  /ge' -cxa **/*.*

या exसंपादक + expandउपयोगिता का उपयोग करके :

$ ex -s +'bufdo!%!expand -t2' -cxa **/*.*

अनुगामी रिक्त स्थान के लिए, देखें: एकाधिक फ़ाइलों के लिए अनुगामी व्हाट्सएप कैसे निकालें?


आप निम्न फ़ंक्शन को अपने में जोड़ सकते हैं .bash_profile:

# Convert tabs to spaces.
# Usage: retab *.*
# See: https://stackoverflow.com/q/11094383/55075
retab() {
  ex +'set ts=2' +'bufdo retab' -cxa $*
}

मैंने इस सूत्र में कई उत्तर दिए हैं, न सिर्फ आपके;; 3 कारण: :retabकाम नहीं कर सकते , शेल ग्लोबिंग इस तरह की चीज़ के लिए एक बुरा समाधान है , आपका :sकमांड किसी भी राशि को 2 स्थानों के साथ बदल देगा (जो आप लगभग कभी नहीं), एक :!expandप्रक्रिया को चलाने के लिए पूर्व शुरू करना मूर्खतापूर्ण है ...
मार्टिन टूरनोइज

... और आपके सभी समाधान द्विआधारी फ़ाइलों और जैसे (.png फ़ाइलें, .pdf फ़ाइलें, आदि) को बंद कर
देंगे

यह दस्तावेज़ीकरण के लिए स्पष्ट रूप से एक भयानक सुझाव है - किसी को इसे समझने में सक्षम होने के लिए कई कार्यक्रमों के काफी अपारदर्शी वाक्यविन्यास और अर्थ संबंधी मुद्दों के साथ परिचित होना है।
जोसिप रॉडिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.