mkdir -p สำหรับไฟล์


24

mkdir -pจะสร้างไดเรกทอรี มันจะสร้างไดเรกทอรีหลักตามต้องการ

คำสั่งที่คล้ายกันมีอยู่สำหรับไฟล์ที่จะสร้างไฟล์และไดเร็กทอรีหลักตามต้องการหรือไม่?


ไม่ใช่ที่ฉันรู้ .. แต่คุณสามารถทำได้ mkdir -p / path / to & make && touch / path / to / file ... ซึ่งจะทำให้ไฟล์ว่างเปล่าในโครงสร้างไดเรกทอรีใหม่ที่คุณสร้างทั้งหมดตามต้องการ

1
@Kansha รวมสิ่งนั้นเข้าด้วยกันdirnameและbasenameเราจะต้องการอาร์กิวเมนต์เดียวเท่านั้น กำไร! :)

ใช่โทรดี

คำตอบ:


29

/dev/nullการติดตั้งจะทำเช่นนี้หากได้รับแฟ้มแหล่งที่มา -Dโต้แย้งว่าการสร้างไดเรกทอรีทั้งหมดแม่:

anthony@Zia:~$ install -D /dev/null /tmp/a/b/c
anthony@Zia:~$ ls -l /tmp/a/b/c 
-rwxr-xr-x 1 anthony anthony 0 Jan 30 10:31 /tmp/a/b/c

ไม่แน่ใจว่าเป็นข้อผิดพลาดหรือไม่พฤติกรรมของไฟล์อุปกรณ์นั้นไม่ได้กล่าวถึงใน manpage คุณสามารถให้ไฟล์เปล่า (เช่นสร้างใหม่ด้วยmktemp) เป็นแหล่งที่มา


7

ไม่มันไม่เท่าที่ฉันรู้ แต่คุณสามารถใช้mkdir -pและtouchกันได้ตลอดเวลา:

f="/a/b/c.txt"
mkdir -p -- "${f%/*}" && touch -- "$f"

3

ฉันพบกับสถานการณ์แบบนี้บ่อยครั้งดังนั้นฉันจึงเขียนฟังก์ชันลงใน.bashrcไฟล์ของฉัน ดูเหมือนว่านี้

function create() {
    arg=$1
    num_of_dirs=$(grep -o "/" <<< $arg | wc -l)
    make_dirs=$(echo $arg | cut -d / -f1-$num_of_dirs)
    mkdir -p $make_dirs && touch $arg
}

ดังนั้นเมื่อฉันต้องการสร้างไฟล์ภายในเส้นทางของไดเรกทอรีที่ไม่มีอยู่ฉันจะพูด

create what/is/it  # will create dirs 'what' and 'is', with file 'it' inside 'is'

1
คนของฉัน! - ขอบคุณฉันโทรไปtouchpแล้วเหมือนกันmkdir -p
ecoologic

0
dir=$(dirname "$f")
test -d $dir || mkdir -p "$dir"

3
testไม่จำเป็นต้อง; mkdir -pไม่ทำอะไรเลยถ้า dir มีอยู่แล้ว ไม่ได้คืนข้อผิดพลาด
Derobert

1
และแน่นอนมันสร้างไดเรกทอรีเท่านั้น
CVn

0

ฉันจะแนะนำเพราะมันเก็บไว้ในหนึ่งบรรทัด แต่การตั้งค่าตัวแปรแยกต่างหากช่วยให้คุณสามารถเปลี่ยนมันและรันคำสั่งจากประวัติอีกครั้งได้อย่างง่ายดาย

B="./make/this/path" && mkdir -p -- "$B" && touch -- "$B/file.txt"

0

เป็นไปได้ที่จะ "ปลอมมัน"

ครั้งแรกบางทฤษฎีที่จำเป็น:

ร็อบ Griffiths โพสต์บทความในปี 2007 ได้รับสิทธิได้อย่างง่ายดายสร้างจำนวนมากโฟลเดอร์ใหม่ใน Macworld.com นั้นเขากล่าวถึงการใช้คำสั่งในการอ่านในรายชื่อของไฟล์ที่จะสร้างไดเรกทอรีใช้xargsmkdir

xargsความสามารถในการอ้างอิงplaceholder( {}) กับธงซึ่งมีค่าสำหรับแต่ละอาร์กิวเมนต์ส่งผ่านไปยัง-I xargsนี่คือความแตกต่างระหว่างกับธงนั้นและไม่มี:

$ foo.txt bar.txt | xargs echo
$ => foo.txt bar.txt
$ foo.txt bar.txt | xargs -I {} echo {}
$ => foo.txt
$ => bar.txt

xargsยังสามารถรันคำสั่งเชลล์โดยพลการด้วยsh -cแฟล็ก:

foo.txt bar.txt | xargs sh -c 'echo arbitrary command!'

การรวมแนวคิด:

เราสามารถรวมแนวคิดเหล่านี้เข้ากับmkdir -pแทนที่จะเป็นmkdirและแนวคิดในคำตอบของ@ldxเพื่อสร้างสิ่งนี้:

$ cat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'

คำสั่งนี้จะแมปชื่อไฟล์แต่ละรายการในรายการไฟล์ที่คั่นด้วยบรรทัดแยกส่วนไฟล์ออกสร้างไดเรกทอรีด้วยmkdir -pแล้วtouchเปลี่ยนชื่อไฟล์ในไดเรกทอรีนั้น ๆ

นี่คือรายละเอียดของสิ่งที่เกิดขึ้นในคำสั่งด้านบน:

พูดถึงตัวอย่างของฉันfiles.txtเช่นนี้:

deeply/nested/foo/bar.txt
deeply/nested/baz/fiz.txt
  • cat files.txt ผลิต deeply/nested/foo/bar.js deeply/nested/baz/fiz.txt
  • deeply/nested/foo/bar.js deeply/nested/baz/fiz.txt ถูกส่งไปยัง xargs
  • เพราะเราใช้-I {}, xargsจะแปลแต่ละโต้แย้งคำสั่งของตัวเองดังนั้นตอนนี้เรามี:
    • deeply/nested/foo/bar.txt
    • deeply/nested/baz/fiz.txt
  • จากนั้นเราเรียกใช้คำสั่งเชลล์ที่ใช้&&combinator เพื่อจัดกลุ่มคำสั่ง 3 ที่รันตามลำดับ - คำสั่งแรกเก็บไฟล์ไว้ในตัวแปรสภาพแวดล้อม (ที่ถูกใช้ซ้ำในไฟล์พาสถัดไป) โดยใช้ตัวแทนที่เราลงทะเบียนไว้ก่อนดังนั้นตอนนี้ มี:
    • f=deeply/nested/foo/bar.txt
    • f=deeply/nested/baz/fiz.txt
  • ตอนนี้เรามีตัวแปรที่เราสามารถส่งผ่านไปmkdir -pได้ แต่เราจำเป็นต้องตัดชื่อไฟล์ออก ง่ายพอที่จะใช้'${f%/*}':
    • mkdir -p deeply/nested/foo/
    • mkdir -p deeply/nested/baz/
  • แล้วเราก็อ้างถึงfตัวแปรทั้งหมดอีกครั้งเมื่อเราtouch:
    • touch deeply/nested/foo/bar.txt
    • touch deeply/nested/baz/fiz.txt

2
คุณมีคำอธิบายทั้งหมดนี้เกี่ยวกับสิ่งที่เป็นหลักcat files.txt | xargs -I {} sh -c 'f="{}" && mkdir -p -- "${f%/*}" && touch -- "$f"'ซึ่งมี UUOC แล้วคุณจะย่อยเป็น xargs ที่ subshells กลับเข้าไปในเปลือกเมื่อwhile readวงทำให้รู้สึกมากขึ้น
Steven Penny

1
ฉันจะยอมรับว่าฉันไม่ได้รับคำสั่งมากที่สุดในคำสั่ง * nix - ฉันไม่รู้ด้วยซ้ำว่า UUOC คืออะไร - แต่ฉันไม่เห็นว่านี่เป็นคำตอบที่น่ากลัวหรือไม่ มันถูกวิจัยทดสอบและเป็นวิธีแก้ปัญหาการทำงานสำหรับคำถามเดิมของคุณ มันสร้างสรรค์ (ซึ่งแตกต่างจากความคิดเห็นที่ค่อนข้างหยาบของคุณ) กรุณาถ้าคุณรู้สึกว่าฉันได้ทำบางสิ่งบางอย่างที่ขาดความรับผิดชอบที่นี่ว่าฉันไม่ควรจะมีแล้วทำอย่างละเอียดต่อไป - อธิบายว่าทำไม ฉันไม่สนใจมากสำหรับการอภิปรายความเห็นที่ไม่มีสาระสำคัญ
razorbeard

1
ความคิดเห็นสุดท้ายของฉันอธิบายได้อย่างสมบูรณ์ while read f; do mkdir -p "$(dirname "$f")"; touch "$f"; done < files.txtคำตอบทั้งหมดของคุณอาจจะเขียนได้ดีขึ้นเป็น ความจริงที่ว่าคุณไม่สามารถค้นหา UUOC ทางอินเทอร์เน็ตเป็นเวลา 10 วินาทีได้ก็เป็นเช่นนั้น
Steven Penny
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.