मैं रिक्त स्थान को विम या लिनक्स में टैब में कैसे बदल सकता हूं?


191

मैंने स्टैक ओवरफ्लो पर कई सवालों पर ध्यान दिया है कि कैसे मैं अपनी ज़रूरत के बिना रिक्त स्थान को टैब में परिवर्तित कर सकता हूं। टैब को रिक्त स्थान में बदलने के तरीके के बारे में अधिक प्रश्न प्रतीत होते हैं, लेकिन मैं इसके विपरीत करने की कोशिश कर रहा हूं।

में Vimमैं कोशिश की है :retabऔर :retab!भाग्य के बिना, लेकिन मेरा मानना है कि ये टैब से रिक्त स्थान के लिए वैसे भी जाने के लिए वास्तव में कर रहे हैं।

मैं दोनों की कोशिश की expandऔर unexpandकमांड प्रॉम्प्ट पर किसी भी भाग्य के बिना।

यहाँ प्रश्न में फ़ाइल है:

http://gdata-python-client.googlecode.com/hg-history/a9ed9edefd61a0ba0e18c43e448472051821003a/samples/docs/docs_v3_example.py

मैं या तो शेल या शेल का उपयोग करके प्रमुख स्थानों को कैसे परिवर्तित कर सकता हूं Vim?


@ मैट की टिप्पणी जो अब हटा दी गई है, पहला उदाहरण ( sed "s/ +/`echo -e '\t'`/g" < input.py > output.py) सभी रिक्त स्थान को परिवर्तित करने के लिए प्रकट होता है, न कि केवल अग्रणी स्थान। दूसरे उदाहरण ( sed "s/^ +/`echo -e '\t'`/g" < input.py > output.py) में यह केवल प्रत्येक पंक्ति पर एक टैब के साथ पहले स्थान को बदलता है और बाकी को छोड़ देता है।
cwd


मुझे सभी / कई फ़ाइलों के लिए उत्तर नहीं मिला , इसलिए मैंने अपना एक लिखा है: stackoverflow.com/a/44581474/1115187 । के साथ find, awkऔर लाठी (टिप्पणियों में इसे छोड़ने के लिए बहुत लंबा है, हालांकि)
अधिकतम

जवाबों:


315

सभी प्रमुख रिक्त स्थान (की तुलना में व्यापक 'tabstop') का विस्तार करने के लिए विम का उपयोग करना , आप उपयोग करने के लिए सही थे, retabलेकिन पहले सुनिश्चित करें कि 'expandtab'यह रीसेट है ( :verbose set ts? et?आपका मित्र है)। retabएक सीमा होती है , इसलिए मैं आमतौर पर %"संपूर्ण फ़ाइल" का अर्थ निर्दिष्ट करता हूं ।

:set tabstop=2      " To match the sample file
:set noexpandtab    " Use tabs, not spaces
:%retab!            " Retabulate the whole file

ऐसा कुछ भी करने से पहले (विशेष रूप से पायथन फ़ाइलों के साथ!), मैं आमतौर पर सेट 'list'करता हूं, ताकि मैं व्हाट्सएप देख सकूं और बदल सकूं।

मैं में निम्नलिखित मानचित्रण है मेरी.vimrc इस बात के लिए:

nnoremap    <F2> :<C-U>setlocal lcs=tab:>-,trail:-,eol:$ list! list? <CR>

2
यहाँ है कैसे मैं यह काम करने के लिए मिला है, यकीन नहीं क्या आवश्यक है और क्या नहीं है, और btw मैं नहीं जानता कि क्या reatab से पहले "%" क्या कर रहा है: :set noet, :set tabstop=2, :retab!, :%retab!, :set tabstop=1, :retab!,:%retab!
CWD

2
मैंने अपना उत्तर अपडेट कर दिया है कि मैं स्पष्टीकरण का उपयोग क्यों करूं %F2 मैपिंग ठीक उसी प्रकार है जैसे यह टाइप किया गया है
जॉन्सवेब

7
उस विशेष फ़ाइल के लिए, मैं बस :set noet ts=2 |%retab!
करूंगा

1
@ जॉनोवेब निष्पक्ष होने के लिए, मैं गलत था: :%retab!अभी भी काम करता है। मैं ==आदि के साथ भ्रमित था , जो संरक्षित सेटिंग का सम्मान करता है
अनक

1
रिक्त स्थान से कॉफ़िशस्क्रिप्ट फ़ाइल को टैब में बदलने के लिए मैंने @ Johnsyweb के उत्तर (.vimrc फ़ाइल के अतिरिक्त सहित) का अनुसरण किया, लेकिन इसके बजाय:set tabstop=4
मिकमस सिप

38

1 - यदि आपके पास स्थान हैं और टैब चाहते हैं।

सबसे पहले, आपको यह तय करने की आवश्यकता है कि कितने स्थानों में एक ही टैब होगा। उस ने कहा, मान लीजिए कि आपके पास प्रमुख 4 रिक्त स्थान हैं, या 8 ... आपके द्वारा यह महसूस किया जाता है कि आप संभवतः 4 स्थान होना चाहते हैं। अब उस जानकारी के साथ, आप करते हैं:

:set ts=4
:set noet
:%retab!

यहाँ एक समस्या है! आदेशों का यह क्रम आपके सभी पाठों के लिए लगेगा, न कि लाइन की शुरुआत में रिक्त स्थान। इसका मतलब है कि एक स्ट्रिंग जैसी: "Hey,␣this␣␣␣␣is␣4␣spaces"बन जाएगी "Hey,␣this⇥is␣4␣spaces", लेकिन इसकी नहीं! यह एक टैब है!

इस छोटे से समस्या मैं एक सिफारिश व्यवस्थित करने के लिए search, के बजाय retab

:%s/^\(^I*\)␣␣␣␣/\1^I/g

यह खोज पूरी फाइल में किसी भी लाइन के लिए शुरू होगी, जो भी टैब की संख्या के साथ है, उसके बाद ४ स्थान हैं, और जो भी टैब मिला उसे एक के लिए स्थानापन्न करें।

यह, दुर्भाग्य से, एक बार में नहीं चलेगा!

सबसे पहले, फ़ाइल में रिक्त स्थान के साथ शुरू होने वाली लाइनें होंगी। खोज तब केवल पहले 4 स्थानों को एक टैब में बदलेगी, और निम्नलिखित ...

आपको कमांड दोहराने की आवश्यकता है। कितनी बार? जब तक आप ए pattern not found। मैं अभी तक इस प्रक्रिया को स्वचालित करने का कोई तरीका नहीं सोच सकता। लेकिन अगर आप करते हैं:

`10@:`

आप शायद कर रहे हैं। यह कमांड अंतिम खोज को दोहराता है / 10 बार प्रतिस्थापित करता है। इसकी संभावना नहीं है कि आपके कार्यक्रम में बहुत सारे संकेत होंगे। यदि ऐसा है, तो फिर से दोहराएं @@

अब बस जवाब पूरा करना है। मुझे पता है कि आपने इसके विपरीत के लिए कहा था, लेकिन आपको कभी नहीं पता कि आपको चीजों को पूर्ववत करने की आवश्यकता है।

2 - आपके पास टैब हैं और रिक्त स्थान चाहते हैं।

सबसे पहले, तय करें कि आप अपने टैब को कितने रिक्त स्थान में बदलना चाहते हैं। कहते हैं कि आप चाहते हैं कि प्रत्येक टैब 2 रिक्त स्थान हो। आप तब करते हैं:

:set ts=2
:set et
:%retab!

यह तार के साथ एक ही समस्या होगी। लेकिन स्ट्रिंग्स के अंदर हार्ड टैब का उपयोग नहीं करने के लिए इसकी बेहतर प्रोग्रामिंग शैली के रूप में, आप वास्तव में यहां एक अच्छी बात कर रहे हैं। यदि आपको वास्तव में स्ट्रिंग के अंदर टैब की आवश्यकता है, तो उपयोग करें \t


एक अत्यंत दुर्लभ जाति की स्थिति लगती है। वैसे भी, जब तक कोई मैच नहीं मिला, दृश्य-श्रंखला चयन और पुनरावृति खोज फ़ंक्शन को स्वीकार करते हुए एक फ़ंक्शन बनाएं, मुझे लगता है कि यह एक अधिक चतुर और उपयोगी उत्तर होगा।
एल्बफैन

हाँ, या वह यदि आप एक अधिक निश्चित समाधान चाहते हैं तो आप एक फ़ंक्शन का उपयोग कर सकते हैं। वैसे भी, यह जानना हमेशा अच्छा होता है कि कैसे करना है ex command, क्योंकि यह वही होगा जो फ़ंक्शन के अंदर है। और नहीं, दुर्लभ नहीं है। तुम सिर्फ एक गड़बड़ है रिक्त स्थान के साथ तार की जरूरत है। दुर्लभ नहीं है। मैं वहाँ जा रहा हूँ। टिप्पणी करने के लिए धन्यवाद।
डॉ। बीईओ

कृपया बताएं कि क्यों / जी प्रत्येक पंक्ति के 4 समूहों के सभी समूहों को टैब में बदलने के लिए पर्याप्त नहीं है, बजाय कई बार खोज चलाने के लिए।
Bjartur Thorlacius

हाय @BjarturThorlacius, समस्या यह है कि यदि आप ^प्रतीक को हटाते हैं , तो लाइन की शुरुआत से खोज शुरू करने के लिए, आप स्ट्रिंग्स के अंदर रिक्त स्थान बदलने का जोखिम उठाते हैं। साथ ^आप गारंटी केवल रिक्त स्थान और टैब बदल रहे हैं लाइन के शुरू, इस प्रकार, खरोज के बाद से। इसके अलावा, अगर आपको यकीन है कि यह सब ^एक साथ करना ठीक है, तो केवल एक बार ही इसे हटाएं और चलाएं::%s/\(^I*\)␣␣␣␣/\1^I/g
Dr Beco

14
:%s/\(^\s*\)\@<=    /\t/g

अनुवाद: 4 लगातार रिक्त स्थान (= वर्ण के बाद) के प्रत्येक उदाहरण के लिए खोजें, लेकिन केवल अगर उस बिंदु तक पूरी लाइन व्हाट्सएप है (यह शून्य-चौड़ाई के पीछे-पीछे जोर का उपयोग करता है \@<=)। टैब वर्ण के साथ प्रत्येक पाया गया उदाहरण बदलें।


1
एकमात्र समाधान जिसने 1 स्थान को 1 टैब तक विस्तारित करने के लिए काम किया , लेकिन उत्तर में यूनिकोड से सावधान रहें, मैंने अभी उपयोग किया :%s/\(^\s*\)\@<= /\t/g- रिक्त स्थान की उपयुक्त संख्या - 4 स्थानों में डालकर 4 टैब में बदलने के लिए)<=
ऑरवेलोफाइल के

5

सभी स्थानों को टैब में बदलता है:% s / \ s / \ t / g


यह वही है जो मुझे चाहिए था। धन्यवाद। केवल एक बदलाव मुझे करना था कि हर एक स्थान को करने के बजाय प्रत्येक 4 स्थानों को टैब के साथ बदलना था।
अनाम व्यक्ति

3

लिनक्स: unexpand(और expand) के साथ

यहाँ एक बहुत अच्छा समाधान है: https://stackoverflow.com/a/11094620/1115187 , ज्यादातर क्योंकि यह * निक्स-यूटिलिटीज का उपयोग करता है:

  1. unexpand - रिक्त स्थान -> टैब
  2. विस्तार - टैब -> रिक्त स्थान

लिनक्स: कस्टम स्क्रिप्ट

मेरा मूल उत्तर

फ़ोल्डर में सभी फ़ाइलों में टैब (पुनरावर्ती) के साथ 4- स्थान इंडेंटेशन ( {4}स्क्रिप्ट में दो हैं ) की जगह के लिए बैश स्निपेट :.py./app

find ./app -iname '*.py' -type f \
    -exec awk -i inplace \
    '{ match($0, /^(( {4})*)(.*?)$/, arr); gsub(/ {4}/, "\t", arr[1]) }; { print arr[1] arr[3] }' {} \; 

यह बीच में या अंत में 4-रिक्त स्थान को संशोधित नहीं करता है।

Ubuntu 16.0x और लिनक्स टकसाल 18 के तहत परीक्षण किया गया था


0

मेरे मामले में, मेरे पास कई स्थान थे (फ़ील्ड एक या अधिक स्थान से अलग हो गए थे) जो मैं एक टैब के साथ बदलना चाहता था। निम्नलिखित ने यह किया:

:% s/\s\+/\t/g

0

आप GNU coreutils स्थापित किया है, पर विचार %!unexpand --first-onlyया 4 अंतरिक्ष टैब के लिए, पर विचार %!unexpand -t 4 --first-only( --first-onlyवर्तमान सिर्फ मामले में अगर आप गलती से लागू किया गया है unexpandके साथ --all)।

ध्यान दें कि यह केवल निर्दिष्ट टैब स्टॉप से ​​पहले के रिक्त स्थान को बदलेगा, कि उन स्थानों को जो उनका अनुसरण करते हैं; जब तक आप टैब को और अधिक शाब्दिक रूप से प्रदर्शित नहीं करते, आपको विम में कोई दृश्य अंतर दिखाई नहीं देगा; उदाहरण के लिए, मेरे ~/.vimrcसम्‍मिलित है set list listchars=tab:▸┈(मुझे संदेह है कि यही कारण है कि आपने सोचा unexpandथा कि काम नहीं किया है)।


0

Vim का उपयोग करने के लिए फ़ाइलों के एक सेट को फिर से शुरू करें (उदाहरण के लिए सभी * .ts फाइलों को एक डायरेक्टरी पदानुक्रम में) 2 रिक्त स्थान से 4 स्थानों तक आप इस कमांड लाइन से आज़मा सकते हैं:

find . -name '*.ts' -print0 | xargs -0 -n1 vim -e '+set ts=2 noet | retab! | set ts=4 et | retab | wq'

यह क्या कर रहा है findसभी मेल करने वाली फ़ाइलों को पास करने के लिए उपयोग कर रहा है xargs(-pr0 विकल्प खोज पर -0 विकल्प के साथ काम करता है -0 xargs करने के लिए नाम में w / रिक्त स्थान को संभालने के लिए)।

xargs -eदिए गए एक्स कमांड को निष्पादित करने वाली प्रत्येक फ़ाइल पर एक्स मोड ( ) में चलता है, जो वास्तव में कई कमांड हैं, मौजूदा प्रमुख स्थानों को टैब में बदलने के लिए, टैब स्टॉप को रीसेट करना और टैब को रिक्त स्थान में बदलना और अंत में सहेजना और बाहर निकलना।

पूर्व मोड में चलने से यह रोकता है: Vim: Warning: Input is not from a terminalप्रत्येक फ़ाइल के लिए।


-1

सरल अजगर स्क्रिप्ट:

import os

SOURCE_ROOT = "ROOT DIRECTORY - WILL CONVERT ALL UNDERNEATH"

for root, dirs, files in os.walk(SOURCE_ROOT):
    for f in files:
        fpath = os.path.join(root,f)
        assert os.path.exists(fpath)
        data = open(fpath, "r").read()
        data = data.replace("    ", "\t")
        outfile = open(fpath, "w")
        outfile.write(data)
        outfile.close()

एक बहुत बड़ा मुद्दा: यह स्निपेट सभी 4-स्पेस की जगह लेता है , न केवल इंडेंटेशन (लाइन की शुरुआत में)
मैक्सकोरुकोव

और दूसरा: फ़ाइल-फ़िल्टर लागू नहीं किया गया है
अधिकतम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.