คุณจะลบช่องว่างต่อท้ายทั้งหมดของโปรเจ็กต์ทั้งหมดได้อย่างไร เริ่มต้นที่ไดเร็กทอรีรูทและลบช่องว่างต่อท้ายออกจากไฟล์ทั้งหมดในโฟลเดอร์ทั้งหมด
นอกจากนี้ฉันต้องการที่จะสามารถแก้ไขไฟล์ได้โดยตรงและไม่ใช่แค่พิมพ์ทุกอย่างเป็น stdout เท่านั้น
คุณจะลบช่องว่างต่อท้ายทั้งหมดของโปรเจ็กต์ทั้งหมดได้อย่างไร เริ่มต้นที่ไดเร็กทอรีรูทและลบช่องว่างต่อท้ายออกจากไฟล์ทั้งหมดในโฟลเดอร์ทั้งหมด
นอกจากนี้ฉันต้องการที่จะสามารถแก้ไขไฟล์ได้โดยตรงและไม่ใช่แค่พิมพ์ทุกอย่างเป็น stdout เท่านั้น
คำตอบ:
นี่คือโซลูชัน OS X> = 10.6 Snow Leopard
มันละเว้นโฟลเดอร์. git และ. svnและเนื้อหา นอกจากนี้จะไม่ทิ้งไฟล์สำรอง
export LC_CTYPE=C
export LANG=C
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
\+
แทน*
ในสตริงแทนที่ - มิฉะนั้นจะตรงกันทุกบรรทัด
sed: RE error: illegal byte sequence
สำหรับฉัน
export LANG=C
และลองอีกครั้ง
export LC_CTYPE=C
เช่นกัน: stackoverflow.com/questions/19242275/…
ใช้:
find . -type f -print0 | xargs -0 perl -pi.bak -e 's/ +$//'
หากคุณไม่ต้องการสร้างไฟล์ ".bak":
find . -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
ในฐานะผู้ใช้ zsh คุณสามารถละเว้นการโทรเพื่อค้นหาและใช้:
perl -pi -e 's/ +$//' **/*
หมายเหตุ: เพื่อป้องกันการทำลายไดเรกทอรีลองเพิ่ม:.git
-not -iwholename '*.git*'
.git
ไดเรกทอรีไม่ว่าจะซ้อนกันลึกแค่ไหนก็ตาม
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
rsync -rv --exclude=.git repo/ repo2/
หลังจากที่มีการเปลี่ยนแปลงในท้องถิ่นrepo
ก็มีความใน repo2
(เสียหาย)
ทางเลือกอีกสองวิธีที่ใช้ได้กับDOS newlines (CR / LF) และทำได้ดีทีเดียวในการหลีกเลี่ยงไฟล์ไบนารี :
โซลูชันทั่วไปซึ่งตรวจสอบว่าประเภท MIME เริ่มต้นด้วยtext/
:
while IFS= read -r -d '' -u 9
do
if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
then
sed -i 's/[ \t]\+\(\r\?\)$/\1/' -- "$REPLY"
else
echo "Skipping $REPLY" >&2
fi
done 9< <(find . -type f -print0)
โซลูชันเฉพาะที่เก็บ Gitโดย Mat ซึ่งใช้-I
ตัวเลือกในgit grep
การข้ามไฟล์ที่ Git ถือว่าเป็นไบนารี:
git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$/\1/'
ใน Bash:
find dir -type f -exec sed -i 's/ *$//' '{}' ';'
หมายเหตุ: หากคุณกำลังใช้ที่.git
เก็บลองเพิ่ม: -not -iwholename '.git'
.
สิ่งนี้ใช้ได้สำหรับฉันใน OSX 10.5 Leopard ซึ่งไม่ใช้ GNU sed หรือ xargs
find dir -type f -print0 | xargs -0 sed -i.bak -E "s/[[:space:]]*$//"
โปรดใช้ความระมัดระวังหากคุณมีไฟล์ที่ต้องยกเว้น (ฉันทำ)!
คุณสามารถใช้ -prune เพื่อละเว้นไดเรกทอรีหรือไฟล์บางไฟล์ สำหรับไฟล์ Python ในที่เก็บ git คุณสามารถใช้สิ่งต่างๆเช่น:
find dir -not -path '.git' -iname '*.py'
find dir -not -path '.git' -iname '*.py' -print0 | xargs -0 sed --in-place=.bak 's/[[:space:]]*$//'
. แทนที่dir
ด้วยไดเร็กทอรีที่เป็นปัญหาเป็นระดับบนสุดเพื่อเรียกคืน
sed -i .bak
? มันควรจะเป็นsed -i.bak
(โดยไม่เว้นวรรค) ไม่ใช่หรือ?
Ack ถูกสร้างมาเพื่องานประเภทนี้
มันใช้งานได้เหมือน grep แต่รู้ว่าจะไม่ลงไปในที่ต่างๆเช่น. svn, .git, .cvs เป็นต้น
ack --print0 -l '[ \t]+$' | xargs -0 -n1 perl -pi -e 's/[ \t]+$//'
ง่ายกว่าการกระโดดผ่านห่วงด้วย find / grep
Ack สามารถใช้ได้ผ่านทางผู้จัดการแพ็คเกจส่วนใหญ่ (เช่นackหรือack-grep )
มันเป็นเพียงโปรแกรม Perl ดังนั้นจึงมีให้บริการในเวอร์ชันไฟล์เดียวที่คุณสามารถดาวน์โหลดและเรียกใช้ได้ โปรดดูที่Ack Install
ack
เป็นเรื่องที่ยอดเยี่ยม ใช้งานมาหลายปีแล้วและมีให้ใช้งานในแพ็คเกจ repos เกือบทั้งหมดสำหรับ distros ส่วนใหญ่
ex
ลองใช้Ex editor (ส่วนหนึ่งของ Vim):
$ ex +'bufdo!%s/\s\+$//e' -cxa **/*.*
หมายเหตุ: สำหรับการเรียกซ้ำ (bash4 & zsh) เราใช้ตัวเลือก globbing ใหม่ ( **/*.*
) เปิดใช้งานโดยshopt -s globstar
.
คุณสามารถเพิ่มฟังก์ชันต่อไปนี้ลงใน.bash_profile
:
# Strip trailing whitespaces.
# Usage: trim *.*
# See: https://stackoverflow.com/q/10711051/55075
trim() {
ex +'bufdo!%s/\s\+$//e' -cxa $*
}
sed
สำหรับการใช้งานsed
ให้ตรวจสอบ: วิธีลบช่องว่างต่อท้ายด้วย sed?
find
ค้นหาสคริปต์ต่อไปนี้ (เช่นremove_trail_spaces.sh
) สำหรับการลบช่องว่างต่อท้ายออกจากไฟล์:
#!/bin/sh
# Script to remove trailing whitespace of all files recursively
# See: /programming/149057/how-to-remove-trailing-whitespace-of-all-files-recursively
case "$OSTYPE" in
darwin*) # OSX 10.5 Leopard, which does not use GNU sed or xargs.
find . -type f -not -iwholename '*.git*' -print0 | xargs -0 sed -i .bak -E "s/[[:space:]]*$//"
find . -type f -name \*.bak -print0 | xargs -0 rm -v
;;
*)
find . -type f -not -iwholename '*.git*' -print0 | xargs -0 perl -pi -e 's/ +$//'
esac
เรียกใช้สคริปต์นี้จากไดเร็กทอรีที่คุณต้องการสแกน บน OSX ในตอนท้ายมันจะลบไฟล์ทั้งหมดที่ลงท้ายด้วย.bak
.
หรือเพียงแค่:
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
ลบช่องว่างต่อท้ายเพียงช่องว่างเดียวแทนที่จะเป็นทั้งหมด
ฉันไม่ได้ใช้การค้นหาและไม่สร้างไฟล์สำรอง
sed -i '' 's/[[:space:]]*$//g' **/*.*
ขึ้นอยู่กับความลึกของโครงสร้างไฟล์ (เวอร์ชันสั้นกว่า) นี้อาจเพียงพอสำหรับความต้องการของคุณ
โปรดทราบว่าสิ่งนี้ใช้ไฟล์ไบนารีด้วยเช่นกัน
แทนที่จะยกเว้นไฟล์นี่คือรูปแบบที่แตกต่างจากด้านบนที่เป็นสีขาวอย่างชัดเจนจะแสดงรายการไฟล์ตามนามสกุลไฟล์ที่คุณต้องการถอดออกอย่าลังเลที่จะลิ้มรส:
find . \( -name *.rb -or -name *.html -or -name *.js -or -name *.coffee -or \
-name *.css -or -name *.scss -or -name *.erb -or -name *.yml -or -name *.ru \) \
-print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
-name "*.rb*"
ฉันลงเอยด้วยการใช้งานสิ่งนี้ซึ่งเป็นการผสมผสานระหว่างเวอร์ชัน pojo และ adams
มันจะทำความสะอาดทั้งช่องว่างต่อท้ายและช่องว่างต่อท้ายอีกรูปแบบหนึ่งคือการส่งคืนรถ:
find . -not \( -name .svn -prune -o -name .git -prune \) -type f \
-exec sed -i 's/[:space:]+$//' \{} \; \
-exec sed -i 's/\r\n$/\n/' \{} \;
มันจะไม่แตะโฟลเดอร์. git ถ้ามี
แก้ไข : ทำให้ปลอดภัยขึ้นเล็กน้อยหลังจากความคิดเห็นไม่อนุญาตให้นำไฟล์ที่มี ".git" หรือ ".svn" อยู่ในนั้น แต่ระวังมันจะไปสัมผัสไฟล์ไบนารีถ้าคุณมี ใช้-iname "*.py" -or -iname "*.php"
หลังจากนั้น-type f
หากคุณต้องการให้สัมผัสเช่น. py และ. php-files
อัปเดต 2 : ตอนนี้แทนที่ช่องว่างทุกชนิดที่ท้ายบรรทัด (ซึ่งหมายถึงแท็บด้วย)
ใช้งานได้ดี .. เพิ่ม / ลบ - รวมสำหรับไฟล์บางประเภท:
egrep -rl ' $' --include *.c * | xargs sed -i 's/\s\+$//g'
ทับทิม:
irb
Dir['lib/**/*.rb'].each{|f| x = File.read(f); File.write(f, x.gsub(/[ \t]+$/,"")) }
ฉันใช้นิพจน์ทั่วไป 4 ขั้นตอน:
วิธีนี้จะลบช่องว่างต่อท้ายทั้งหมดในตอนท้ายของแต่ละบรรทัดในไฟล์ทั้งหมด และคุณสามารถยกเว้นไฟล์บางไฟล์ที่ไม่ตรงกับความต้องการนี้ได้
1) ใช้คำตอบอื่น ๆ อีก-E
มากมาย ฉันไม่แน่ใจว่าทำไมเนื่องจากเป็นตัวเลือกที่เข้ากันได้กับ BSD ที่ไม่มีเอกสาร-r
ควรใช้แทน
2) -i ''
การใช้คำตอบอื่น นั่นควรจะเป็นเพียง-i
(หรือ-i''
ถ้า preffered) เพราะ-i
มีคำต่อท้ายทันที
3) Git โซลูชันเฉพาะ:
git config --global alias.check-whitespace \
'git diff-tree --check $(git hash-object -t tree /dev/null) HEAD'
git check-whitespace | grep trailing | cut -d: -f1 | uniq -u -z | xargs -0 sed --in-place -e 's/[ \t]+$//'
รายการแรกลงทะเบียนนามแฝง git check-whitespace
ซึ่งแสดงรายการไฟล์ที่มีช่องว่างต่อท้าย อันที่สองทำงานsed
กับพวกเขา
ผมเพียง แต่ใช้\t
มากกว่า[:space:]
ที่ผมไม่มักจะเห็นแท็บแนวตั้งฟีดรูปแบบและช่องว่างที่ไม่เปราะ การวัดของคุณอาจแตกต่างกันไป
นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน (MacOS X 10.8, GNU sed ติดตั้งโดย Homebrew):
find . -path ./vendor -prune -o \
\( -name '*.java' -o -name '*.xml' -o -name '*.css' \) \
-exec gsed -i -E 's/\t/ /' \{} \; \
-exec gsed -i -E 's/[[:space:]]*$//' \{} \; \
-exec gsed -i -E 's/\r\n/\n/' \{} \;
ลบออกช่องว่างต่อท้ายแทนที่แท็บที่มีช่องว่างแทนที่ของ Windows CRLF \n
กับระบบปฏิบัติการยูนิกซ์
สิ่งที่น่าสนใจคือฉันต้องเรียกใช้สิ่งนี้ 3-4 ครั้งก่อนที่ไฟล์ทั้งหมดจะได้รับการแก้ไขโดยgsed
คำแนะนำในการทำความสะอาดทั้งหมด