ลบโฟลเดอร์เปล่าทั้งหมดแม้จะมีโฟลเดอร์. svn อยู่ด้วย


6

ฉันพยายามลบโฟลเดอร์เปล่าทั้งหมดในไดเรกทอรี แต่find . -type f -emptyไม่พบอะไรเลยเพราะทุกโฟลเดอร์ที่มีซ่อน.svnโฟลเดอร์

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร


เป็น.svnไดเรกทอรีว่าง?
Dennis Williamson

ไม่พวกเขาไม่ได้เป็น. ฉันคิดว่าวิธีแก้ปัญหา Ollis จะทำงานได้ อย่างไรก็ตามฉันยังไม่ได้ทดสอบ
atamanroman

คำตอบ:


1

หากทำได้คุณสามารถปิดหลักสูตรได้ก่อนลบ.svnโฟลเดอร์ทั้งหมด ข้อเสีย: คุณจะสูญเสียข้อมูลการควบคุมเวอร์ชันหากมีผู้ใช้ SVN หากมีใครใช้ SVN อยู่ก็ไม่ควรเอาโฟลเดอร์เหล่านั้นออก (หรือจริงๆแล้วคุณต้องลบออกจาก SVN ด้วยเช่นกันเพราะ SVN กำลังติดตามโฟลเดอร์และไฟล์)

หากไม่สามารถทำได้ฉันจะไปกับเส้นทางการเขียนสคริปต์:

for folder in $(find . -type d); do
 if [ "`ls $folder | wc -l`" -eq 0 ]; then
  echo "I am going to delete $folder"
 fi
done

ก่อนอื่นให้ลองทำการทดสอบเพราะอาจมีบางสิ่งที่น่าแปลกใจ จากนั้นคุณสามารถเปลี่ยนแทนว่าrm -recho

อย่างไรก็ตามโปรดทราบว่าการดำเนินการนี้จะลบโฟลเดอร์ทั้งหมดที่มีเฉพาะไฟล์ดอทเท่านั้น (ตัวอย่างเช่นa/.this_is_super_importantจะถูกลบหากไม่มีไฟล์หรือโฟลเดอร์อื่น)


3

การปรับเปลี่ยนเล็กน้อย (เพียงพิมพ์ไดเรกทอรีและไพพ์ลงในxargsภายหลัง):

for folder in $(find -type d ! -path *.svn*); do
  if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
    echo $folder
  fi
done

วางสิ่งนี้ลงในของคุณ$PATHอาจเป็นsvn-emptiesแล้วเรียกใช้ครั้งแรก:

svn-empties

เพื่อแสดงรายการไดเร็กทอรีที่พบ (แก้ไขรายการถ้าจำเป็น) จากนั้นไพพ์ลงในxargs:

svn-empties | xargs svn rm

สคริปต์นี้มีประโยชน์มากสำหรับฉันในขณะที่ใช้git-svn(ขอบคุณ!) เนื่องจากgitไม่ได้ติดตามไดเรกทอรีที่ว่างเปล่าฉันสามารถจบลงด้วยไดเรกทอรีที่ว่างเปล่าจำนวนมากในพื้นที่เก็บข้อมูลการโค่นล้ม ฉันsvn coเป็นสำเนาของที่เก็บแยกต่างหากและเรียกใช้svn-empties | xargs svn rmเป็นระยะ การใช้การโค่นล้มในตอนแรกไม่ใช่การตัดสินใจของฉัน)


หากคุณกำลังใช้git-svnคุณอาจต้องการที่จะใช้ตัวเลือกในการ--rmdir git svn dcommitมันจะดูแลการลบไดเรกทอรีจาก svn ทันทีที่ว่างเปล่า
gioele

2

ฉันเพิ่งสะดุดกับเรื่องนี้และฉันใช้สคริปต์นี้ แต่แก้ไขเพื่อพิจารณา dirs ที่ว่างเปล่าเฉพาะคนที่มี. svn และไม่มีไฟล์อื่นซ่อนหรือปกติ

นอกจากนี้โปรดจำไว้ว่าฉันใช้ svn rm ดังนั้นจึงควรทำงานกับที่เก็บคุณสามารถปรับสคริปต์เพื่อทำสิ่งต่าง ๆ ในไดเรกทอรี

for folder in $(find -type d ! -path *.svn*); do
  if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
    svn rm $folder
  fi
done

0

เพื่อหลีกเลี่ยงปัญหาเกี่ยวกับพื้นที่สีขาวfindและIFSเวทย์มนตร์ (ชื่อไฟล์สามารถมีการขึ้นบรรทัดใหม่ได้เช่นกันดังนั้นจึงIFS=$'\n'ไม่ใช่กระสุนเงิน) จึงสามารถใช้ globs และอาร์เรย์ได้

#!/bin/bash
search_dir=${1:-.}
shopt -s globstar dotglob
for svn_dir in "$search_dir"/**/.svn/; do
    base_dir=${svn_dir%/.svn/}
    base_dir_contents=("$base_dir"/*)
    if [ ${#base_dir_contents[@]} -eq 1 ]; then
        printf 'The directory "%s" only contains ".svn/".\n' "$base_dir"
    fi
done
  • สคริปต์ใช้อาร์กิวเมนต์ที่เป็นทางเลือกหรือใช้เส้นทางปัจจุบันเป็นค่าเริ่มต้นหากไม่มี
  • globstarเปิดใช้**งานโครงสร้างการสำรวจไดเรกทอรี
  • dotglob รวมไฟล์ที่ซ่อนอยู่ในเครื่องหมายดอกจัน globs
  • forglob ควรจะปลอดภัยกับตัวละครชื่อไดเรกทอรีใด ๆ ที่มีปัญหา ก้อนจะเสมอขยายอย่างปลอดภัยในทุบตีซึ่งไม่ได้เป็นกรณีที่มีls, findฯลฯ เฉือนท้ายทำให้แน่ใจว่าเราจะตรงกับโฟลเดอร์ชื่อ.svnและไม่ไฟล์ปกติ (กรณีมุมจริงแม้ว่า)
  • ชื่อของไฟล์ที่อยู่ในโฟลเดอร์ที่มี.svnไดเรกทอรีที่ตรงกันจะถูกทำให้กลมเป็นอาร์เรย์ หากจำนวนรายการในอาร์เรย์นี้เป็น 1 (เช่น.svnโฟลเดอร์ที่เราสร้างโดยรู้ * มี) แสดงว่าเป็นสิ่งที่เรากำลังมองหา

มันใช้ Bash ในตัวเท่านั้นจึงน่าจะเร็วกว่าการออกระบบเสริมสำหรับfindแต่ความแตกต่างนั้นไม่น่าจะสังเกตได้ชัดเจนและ I / O จะเป็นคอขวดหลักต่อไป


*: sidenote เล็กน้อย (ใช้กับโซลูชันอื่น ๆ เช่นกัน): มีเงื่อนไขการแข่งขันที่เป็นไปได้หากมีเช่น.svnและfooไฟล์ในไดเรกทอรีเท่านั้นและ.svnไดเรกทอรีจะถูกลบออกระหว่างforและอาร์เรย์ glob ซึ่งจะส่งผลให้fooถูกลบออก เช่นกัน อย่างไรก็ตามหากผู้ที่มีเจตนาร้ายมีสิทธิ์ลบไฟล์ในระบบไฟล์เกมอาจหายไปแล้วและสามารถลบออกได้ง่ายกว่าการโจมตีตามจังหวะเวลา


อีกพูดถึงอย่างรวดเร็วคือคำตอบอื่น ๆ ควรอ้างอิง*.svn*การขยายตัวของพวกเขา มิฉะนั้นfindคำสั่งจะล้มเหลวหากโฟลเดอร์ปัจจุบันมีไฟล์ที่ตรงกับ glob:

$ mkdir foo && cd foo
$ mkdir -p test1/.svn test2
$ find -type d ! -path *.svn*
.
./test1
./test2
$ touch foo.svnbar
$ find -type d ! -path *.svn*
.
./test1
./test1/.svn
./test2
$ find -type d ! -path "*.svn*"
.
./test1
./test2

โดยไม่ต้องคำพูดจะขยายก่อนเวลาอันควรโดยเปลือกไป*.svn*foo.svnbar


0
  1. แก้ไขปัญหาที่: ช่องว่างใน Path
  2. สามารถเรียกใช้สคริปต์ด้วยพารามิเตอร์ PATH ดังนี้:

svn-empties YOU_WANT_TO_SEARCH_PATH

C_IFS=$IFS

IFS=$'\n'

for folder in $(find "$1" -depth -type d ! -path *.svn*|sort -r); do
  counts=$(find "$folder" -type f ! -path *.svn* ! -path $folder | wc -l)

  if [ $counts -eq 0 ]; then
    echo $folder
  fi

done

IFS=$C_IFS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.