बिना डायरेक्टरी को शामिल किए मैं फ़ाइलों और फ़ोल्डरों की निर्देशिका को कैसे टारगेट करूं?


382

मैं आमतौर पर करता हूं:

tar -czvf my_directory.tar.gz my_directory

क्या होगा अगर मैं सिर्फ my_directory में सब कुछ शामिल करना चाहता हूं (किसी भी छिपी हुई सिस्टम फ़ाइलों सहित), लेकिन निर्देशिका ही नहीं? मैं नहीं चाहता:

my_directory
   --- my_file
   --- my_file
   --- my_file

मुझे चाहिए:

my_file
my_file
my_file

क्या ऐसा करने का डिफ़ॉल्ट व्यवहार है tar -czf? मेरे मामले में यह केवल फाइलों को संग्रहीत कर रहा है और निर्देशिका को नहीं। जब मैं सिर्फ tarडायरेक्टरी को इसमें शामिल करता हूं , लेकिन इसके साथ tar -czfकेवल फाइलों को जोड़ रहा है।
दुर्गा स्वरूप

जवाबों:


233
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd - 

एक लाइन में काम करना चाहिए। यह छिपी हुई फ़ाइलों के लिए भी अच्छी तरह से काम करता है। * "" कम से कम बैश में पथ नाम विस्तार से छिपी हुई फ़ाइलों का विस्तार नहीं करता है। नीचे मेरा प्रयोग है:

$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2

2
यह रिक्त स्थान या अन्य विशेष वर्णों वाली फ़ाइलों पर भी काम करेगा। बहुत बढ़िया!
PanCrit

29
सही नहीं है - टार फ़ाइल में '।' और भी ./file1 के बजाय सिर्फ फ़ाइल 1। मैं नीचे mateusza द्वारा समाधान का उपयोग करना पसंद करता हूं - un-tarring जब -स्ट्रिप-घटक।
इवान

23
@Ivan अगर आप को बदलने के .साथ *इतना आदेश हो जाएगा cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..तो यह के रूप में आप की उम्मीद काम करेंगे।
बेनामी

3
@jmathew आप एक उप-प्रकार का भी उपयोग कर सकते हैं ताकि आपके वर्तमान शेल की कार्यशील निर्देशिका परिवर्तित न हो:$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
Alec

मुझे पता है कि यह एक पुराना उत्तर है, लेकिन cdनिर्देशिकाओं में शामिल है और बाहर बहुत लंगड़ा है। कम से कम उपयोग कर सकते हैं pushdऔर popdअगर tarकोई झंडे की तरह नहीं है -C
एंड्री

667

-Cटार के स्विच का उपयोग करें :

tar -czvf my_directory.tar.gz -C my_directory .

-C my_directoryटार बताता है करने के लिए वर्तमान निर्देशिका बदलने के लिए my_directory, और फिर .इसका मतलब है (छुपा फ़ाइलों और उप-निर्देशिका सहित) "पूरे वर्तमान निर्देशिका जोड़ें"।

सुनिश्चित करें कि आप ऐसा करने -C my_directoryसे पहले करते हैं .या आपको वर्तमान निर्देशिका में फ़ाइलें मिलेंगी।


5
+1 धन्यवाद! यह लानत थी '।' में गुम हो गया था। इतना
उग्र

14
"सबसे विकल्प के विपरीत, -सी बात यह फ़ाइलों संसाधित करने के लिए सूची में स्थित होता है पर संसाधित किया जाता है निम्न आदेश पर विचार करें:। tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a" Apl.jhu.edu/Misc/Unix-info/tar/tar_65.html मैं हमेशा कोशिश tar -czvf my_directory.tar.gz * -C my_directoryऔर वह काम नहीं करता। -Cस्थान महत्वपूर्ण है! धिक्कार है तर ...
m-ric

57
सही नहीं है - टार फ़ाइल में '।' और भी ./file1 के बजाय सिर्फ फ़ाइल 1। मैं नीचे mateusza द्वारा समाधान का उपयोग करना पसंद करता हूं - un-tarring जब -स्ट्रिप-घटक।
इवान

3
@ सल्फर: शेल टार चलाने से पहले वाइल्डकार्ड को प्रतिस्थापित करता है। यह भी ध्यान दें कि वाइल्डकार्ड का उपयोग *करने से छिपी हुई फाइलें (जो मूल आवश्यकता थी) शामिल नहीं होंगी।
डबेक

28
यह बनाता है । जड़ निर्देशिका के रूप में .tar.gz
बेनामी

59

आप हमेशा की तरह संग्रह भी बना सकते हैं और इसके साथ इसे निकाल सकते हैं:

tar --strip-components 1 -xvf my_directory.tar.gz

3
यह समाधान उन स्थितियों में विशेष रूप से अच्छा है जहां आप अपनी सभी आवश्यकताओं को जानने से पहले बनाए गए टारबॉल के साथ काम कर रहे हैं ...
Digger

2
मन जो --strip-componentsएक GNU एक्सटेंशन है।
zneak

2
संदर्भ में "हमेशा की तरह" उदाहरण प्रदान करके इस उत्तर को बेहतर बनाया जा सकता है।
जोश हबदास

33

--transform/ पर एक नज़र है --xform, यह आपको फ़ाइल नाम को मालिश करने का अवसर देता है क्योंकि फ़ाइल को संग्रह में जोड़ा जाता है:

% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz 
file2
.hiddenfile1
.hiddenfile2
file1

ट्रांसफ़ॉर्म एक्सप्रेशन उसी के समान है sed, और हम /( ,उपरोक्त उदाहरण में) के अलावा अन्य विभाजकों का उपयोग कर सकते हैं ।
https://www.gnu.org/software/tar/manual/html_section/tar_52.html


3
मैं यह करूँगा। और कुछ भी सिर्फ एक हैक है!
jwg

2
यह एक बेहतर उपाय है।
लीसी

यह सबसे अच्छा उपाय है।
जस्टफॉल

1
अच्छा समाधान, लेकिन यह कारण हो सकता है file list too longमेरा समाधान यही रोकता है और अधिक लचीला भी है।
मार्स'

यह एक बेहतरीन उपाय है। आप --xformकई रास्तों के लिए कई बार पास भी कर सकते हैं।
एलिग

26

टी एल; डॉ

find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

कुछ शर्तों के साथ (केवल फ़ाइलें, डीआईआर और सिमिलिंक संग्रह):

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

व्याख्या

नीचे दुर्भाग्य ./से संग्रह में एक मूल निर्देशिका शामिल है :

tar -czf mydir.tgz -C /my/dir .

आप --transformकॉन्फ़िगरेशन विकल्प का उपयोग करके उस निर्देशिका से सभी फ़ाइलों को स्थानांतरित कर सकते हैं , लेकिन इससे .निर्देशिका से छुटकारा नहीं मिलता है। कमांड को वश में करना मुश्किल हो जाता है।

आप $(find ...)कमांड में फ़ाइल सूची जोड़ने के लिए उपयोग कर सकते हैं (जैसे कि मैग्नस के उत्तर में ), लेकिन यह संभावित रूप से "फ़ाइल सूची बहुत लंबी" त्रुटि का कारण बनता है। सबसे अच्छा तरीका यह है कि इसे तार के -Tविकल्प के साथ मिलाएं , जैसे:

find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

मूल रूप से यह जो करता है वह आपकी निर्देशिका के तहत सभी फाइलों ( -type f), लिंक ( -type l) और उपनिर्देशिकाओं ( -type d) की सूची है, सभी फाइलनामों का उपयोग करके सापेक्ष बनाते हैं -printf "%P\n", और फिर टार कमांड को पास करते हैं (यह एसटीडीएन का उपयोग करके फाइलनेम लेता है -T -)। -Cविकल्प की जरूरत है ताकि टार जानता है, जहां रिश्तेदार नाम के साथ फ़ाइलें स्थित हैं है। --no-recursionझंडा ताकि टार फ़ोल्डरों यह (डुप्लिकेट फ़ाइलें के कारण) संग्रह करने के लिए कहा है में recurse नहीं करता है।

यदि आपको फ़ाइल नाम के साथ कुछ विशेष करने की आवश्यकता है (फ़िल्टरिंग, सिम्बलिंक का पालन करना आदि), तो findकमांड बहुत शक्तिशाली है, और आप इसे tarउपरोक्त कमांड के भाग को हटाकर इसका परीक्षण कर सकते हैं :

$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore

उदाहरण के लिए यदि आप पीडीएफ फाइलों को फ़िल्टर करना चाहते हैं, तो जोड़ें ! -name '*.pdf'

$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore

गैर-जीएनयू पाते हैं

कमांड printf(GNU में उपलब्ध find) का उपयोग करता है जो findसापेक्ष परिणामों के साथ इसके परिणामों को प्रिंट करना बताता है। हालाँकि, यदि आपके पास GNU नहीं है find, तो यह पथ को सापेक्ष बनाने के लिए काम करता है (माता-पिता को निकालता है sed):

find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -

2
बहुत बढ़िया जवाब। बहुत विस्तृत, और सबसे महत्वपूर्ण बात, समस्या को पूरी तरह हल करता है।
एलेक्स

16

यह उत्तर अधिकांश स्थितियों में काम करना चाहिए। हालाँकि, उदाहरण के लिए, फ़ाइल नाम को केवल फ़ाइल के ./file1बजाय टार फ़ाइल में कैसे संग्रहीत किया जाता है, पर ध्यान दें file1। मैंने पाया कि इस विधि का उपयोग करते समय समस्याएँ पैदा हुईं बिल्ड बिल्ड में पैकेज फ़ाइलों के रूप में उपयोग किए जाने वाले टारबॉल को हेरफेर करने के लिए ।

एक समाधान ..इस तरह के अलावा सभी फ़ाइलों को सूचीबद्ध करने के लिए कुछ बैश ग्लब्स का उपयोग करना है :

tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *

यह एक चाल है जो मैंने इस उत्तर से सीखी ।

अब टार एक त्रुटि लौटाएगा यदि कोई फ़ाइल मिलान नहीं है ..?*या .[^.]*, लेकिन यह अभी भी काम करेगा। यदि त्रुटि एक समस्या है (आप एक स्क्रिप्ट में सफलता के लिए जाँच कर रहे हैं), यह काम करता है:

shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob

हालाँकि अब हम शेल विकल्पों के साथ खिलवाड़ कर रहे हैं, हम यह तय कर सकते हैं कि यह *छिपी हुई फाइलों से मेल खाने वाला है:

shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob

यह काम नहीं कर सकता है जहाँ आपका शेल *मौजूदा निर्देशिका में ग्लोब करता है, इसलिए वैकल्पिक रूप से, उपयोग करें:

shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob

1
जब मैं ऐसा करता हूं तो मुझे बहुत अधिक त्रुटियां होती हैं। यह tar: start.sh: Cannot stat: No such file or directoryमेरी वर्तमान निर्देशिका की सभी फाइलों में होता है! मैं इससे कैसे बचूं?
ब्रेनस्टोन

@BrainStone मैं बिल्कुल वही परिणाम प्राप्त करता हूं।
mbmast

15
cd my_directory
tar zcvf ../my_directory.tar.gz *

2
हाल ने स्पष्ट रूप से छिपी हुई फ़ाइलों के बारे में पूछा। तुम भी जरूरत है ।??*।
पैनक्रिट

2
-1: यह टार में छिपी हुई फाइलों को नहीं जोड़ता है। देखिए tbman का जवाब
डबेक

3

यदि यह एक यूनिक्स / लिनक्स प्रणाली है, और आप छिपी हुई फाइलों की परवाह करते हैं (जो कि * द्वारा याद किया जाएगा), आपको करने की आवश्यकता है:

cd my_directory
tar zcvf ../my_directory.tar.gz * .??*

मुझे नहीं पता कि विंडोज के नीचे छिपी हुई फाइलें कैसी दिखती हैं।


2

मैं निम्नलिखित बैश फ़ंक्शन का प्रस्ताव करता हूं (पहला तर्क डायर के लिए रास्ता है, दूसरा तर्क परिणामस्वरूप संग्रह का आधार है):

function tar_dir_contents ()
{
    local DIRPATH="$1"
    local TARARCH="$2.tar.gz"
    local ORGIFS="$IFS"
    IFS=$'\n'
    tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
    IFS="$ORGIFS"
}

आप इसे इस तरह से चला सकते हैं:

$ tar_dir_contents /path/to/some/dir my_archive

और यह my_archive.tar.gzवर्तमान निर्देशिका के भीतर संग्रह उत्पन्न करेगा । यह छिपे हुए (*।) तत्वों के साथ और उनके फ़ाइलनाम में रिक्त स्थान वाले तत्वों के साथ काम करता है।



1
tar.create() {
        local folder="${1}"

        local tar="$(basename "${folder}")".tar.gz

        cd "${folder}" && tar -zcvf "../${tar}" .; cd - &> /dev/null
}

उदाहरण:

tar.create folder

आपका स्वागत है।


1

मेरे लिए यही काम करता है।

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')

आप भी इस्तेमाल कर सकते हैं

tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')

पहले आदेश में, खोजने फ़ाइलें और की उप-निर्देशिका की सूची लौटाता है my_dir । हालाँकि, निर्देशिका my_dir स्वयं उस सूची में 'के रूप में शामिल है।' -Printf पैरामीटर कि सहित पूरा पथ को हटा '।' और यह भी सब हालांकि Printf के प्रारूप स्ट्रिंग '% P' में my_dir की फ़ाइलों और उप-निर्देशिकाओं की सूची में एक अवशेष छोड़ दिया जाता है और खोज कमांड के परिणाम में एक अग्रणी स्थान द्वारा देखा जा सकता है ।

यह TAR के लिए कोई समस्या नहीं होगी, लेकिन यदि आप इसे ठीक करना चाहते हैं, तो दूसरे कमांड में 1 -mindepth जोड़ें ।


0

पैक्स का उपयोग करें।

पैक्स एक पदावनत पैकेज है, लेकिन काम पूरी तरह से और एक साधारण फैशन में करता है।

pax -w > mydir.tar mydir

सबसे व्यावहारिक और नौकरी करता है +1
ब्रेनो सालगाड़ो

यह आदेश सामग्री के साथ mydir.tar बनाता है: mydir / file1 mydir / file2, वास्तव में जिसे टाला जाना था।
एलेक्स

0

सबसे आसान तरीका मैंने पाया:

cd my_dir && tar -czvf ../my_dir.tar.gz *


1
जिसमें छिपी हुई फाइलें शामिल नहीं होंगी।
asynts

0
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
    { cd "$1" && find -type f -print0; } \
    | cut --zero-terminated --characters=3- \
    | tar --create --file="$2" --directory="$1" --null --files-from=-
}

सुरक्षित रूप से रिक्त स्थान या अन्य असामान्य पात्रों के साथ फ़ाइल नाम संभालता है। आप वैकल्पिक रूप से -name '*.sql'शामिल फ़ाइलों को सीमित करने के लिए खोज कमांड में एक या समान फ़िल्टर जोड़ सकते हैं।


-1
 tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*

यदि फ़ोल्डर mytemp है तो यदि आप उपरोक्त को लागू करते हैं तो यह ज़िप करेगा और फ़ोल्डर में सभी फ़ाइलों को हटा देगा, लेकिन इसे अकेला छोड़ दें

 tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*

आप अपवर्जित पैटर्न दे सकते हैं और यह भी निर्दिष्ट कर सकते हैं कि सबफ़ोल्डर्स को भी न देखें


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