ฉันมีไฟล์จำนวนมากที่มีแท็บเกลื่อนไปทั่วและฉันต้องการแปลงให้เป็นช่องว่าง ฉันรู้เกี่ยวกับexpandคำสั่ง แต่น่าเสียดายที่ฉันจะต้องพิมพ์ทุกไฟล์เดียวใช้มัน มีวิธีใดที่ง่ายกว่าในการทำเช่นนี้บน Linux?
ฉันมีไฟล์จำนวนมากที่มีแท็บเกลื่อนไปทั่วและฉันต้องการแปลงให้เป็นช่องว่าง ฉันรู้เกี่ยวกับexpandคำสั่ง แต่น่าเสียดายที่ฉันจะต้องพิมพ์ทุกไฟล์เดียวใช้มัน มีวิธีใดที่ง่ายกว่าในการทำเช่นนี้บน Linux?
คำตอบ:
ลองทำสิ่งต่อไปนี้:
find ./ -type f -exec sed -i 's/\t/ /g' {} \;
หากคุณต้องการช่องว่างสี่ลอง:
find ./ -type f -exec sed -i 's/\t/ /g' {} \;
's/\t/ /g'แทนที่มากกว่าหนึ่งแท็บต่อบรรทัด
find ./ -type f -exec sed -i ’s/\t/ /g’ {} +" (นั่นคือ " +" แทนที่จะเป็น " \;") ถ้าfindรุ่นรองรับมัน (และฉันไม่ได้พบกับรุ่นที่ไม่เป็นส่วนตัว แต่มันไม่ใช่มาตรฐาน POSIX ดังนั้นฉันเดาว่ามันอาจเกิดขึ้นได้ในบางระบบดู " -exec command {} +" ในคู่มือ) แทนที่จะเรียกใช้หนึ่งอินสแตนซ์sedสำหรับทุกไฟล์สิ่งนี้จะสร้างรายการอาร์กิวเมนต์ที่มีอาร์กิวเมนต์ชื่อไฟล์มากที่สุดเท่าที่ระบบรองรับ ( getconf ARG_MAX= 2097152 บนระบบของฉัน) เหมือนxargsและเปิดใช้sedกระบวนการน้อยลง
sedไม่เข้าใจ\tลำดับการยกเว้นแท็บ [Ctrl]+V, [Tab]คุณสามารถแทนที่ด้วยอักขระแท็บตัวอักษรที่คุณสามารถใส่ในเปลือกโดย
มีหลายวิธีในการทำเช่นนี้ นอกจากนี้ยังมีวิธีการยิงตัวเองมากมายในขณะที่ทำเช่นนี้หากคุณไม่ระวังหรือหากคุณยังใหม่กับ Linux ตามที่ปรากฏ สมมติว่าคุณสามารถสร้างรายการไฟล์ที่คุณต้องการแปลงไม่ว่าจะโดยการใช้อะไรที่ชอบfindหรือด้วยตนเองกับโปรแกรมแก้ไขเพียงแค่ไพพ์รายการนั้นลงในรายการต่อไปนี้
while read file
do
expand "$file" > /tmp/expandtmp
mv /tmp/expandtmp "$file"
done
วิธีหนึ่งที่คุณสามารถยิงด้วยเท้านั้นคือการพิมพ์ผิดเพื่อให้คุณหมุนไฟล์เปล่าให้กับชื่อไฟล์ทั้งหมดที่คุณระบุดังนั้นการลบเนื้อหาของไฟล์ทั้งหมดของคุณ ดังนั้นควรระมัดระวังและทดสอบสิ่งที่คุณทำก่อนในไฟล์ชุดเล็ก ๆ ที่คุณสำรองไว้
mvเงื่อนไขเกี่ยวกับความสำเร็จของexpand:expand ... && mv ...
expand -t 4ขยายแท็บเป็น 4 ช่องว่าง นอกจากนี้วิธีนี้สามารถสร้างการขึ้นบรรทัดใหม่ แต่อย่างอื่นมันใช้งานได้
find . -type f -iname "*.js" -print0 | xargs -0 -I foo tab2space foo foo
-I foo สร้างตัวแปรแม่แบบ foo สำหรับแต่ละบรรทัดอินพุตดังนั้นคุณสามารถอ้างถึงอินพุตมากกว่าหนึ่งครั้ง
-print0และ-0บอกให้ทั้งสองคำสั่งใช้ \ 0 เป็นตัวคั่นบรรทัดแทน SPACE ดังนั้นคำสั่งนี้จะทำงานกับพา ธ ที่มีช่องว่าง
find -name \*.js -exec bash -c 'expand -t 4 "$0" | tee "$0"' {} \;
ข้อด้อย:
ไฟล์ที่มีขนาดใหญ่กว่าขนาดบัฟเฟอร์ของท่อ ( 64KB ) จะถูกตัดทอน
ข้อดี:
ไม่มีไฟล์ temp ที่
ใหญ่กว่าขนาดบัฟเฟอร์ของท่อถูกตัดทอน
สิ่งนี้ดีกว่า:
find . -name *.java ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
/tmp/eเพราะหากมีสิ่งอื่นใดที่ใช้ไฟล์นั้นสิ่งนี้จะทำให้ยุ่งเหยิง เช่นถ้าผู้ใช้สองคนต้องการใช้สิ่งนี้ในเวลาเดียวกัน
ฉันให้ปัญหานี้โดยคำนึงถึงข้อกำหนดต่อไปนี้:
ความต้องการครั้งสุดท้ายเป็นสิ่งที่ยากที่สุดที่จะทำเพราะ "ขยาย" ไม่อนุญาตให้แก้ไขไฟล์ที่มีอยู่
ฉันคิดวิธีแก้ปัญหาต่อไปนี้ขึ้นมา:
find . -type f -regextype egrep -regex '.*\.(c|cpp|h|hpp)' -print0 | xargs -0 -n 1 -P 10 -IFILE bash -c ' ( echo "Processing FILE..." && expand -t 4 "FILE" > /tmp/expand.$$ && mv /tmp/expand.$$ "FILE" ) || exit 255'
นี่คือคำอธิบายบางอย่าง:
expandฉันถือว่า s / เขาต้องการการจัดตำแหน่งของข้อความที่เก็บรักษาไว้