ฉันมีไฟล์จำนวนมากที่มีแท็บเกลื่อนไปทั่วและฉันต้องการแปลงให้เป็นช่องว่าง ฉันรู้เกี่ยวกับ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 / เขาต้องการการจัดตำแหน่งของข้อความที่เก็บรักษาไว้