วิธีแก้ไขไฟล์ข้อความหลายไฟล์ด้วยคำสั่งเดียว?


18

ฉันต้องการลบบรรทัดแรกของไฟล์ข้อความหลายไฟล์และแทนที่ด้วยบรรทัดอื่น มีวิธีทำเช่นนี้โดยใช้ terminal หรือไม่

ฉันรู้วิธีใช้เสียงเรียกเข้ามีวิธีทำให้เป็นอัตโนมัติหรือไม่ ฉันต้องการหลีกเลี่ยงการทำด้วยตนเอง (เช่นเดียวกับการแก้ไขแต่ละไฟล์)

ถ้าเป็นไปได้ฉันต้องการหลีกเลี่ยงการติดตั้งไลบรารีใหม่ (โดยเฉพาะอย่างยิ่งสิ่งที่ฉันคิดว่าง่ายมาก - แต่ฉันอาจผิด)

ขอบคุณล่วงหน้า!

คำตอบ:


21

คุณสามารถใช้sed:

sed -i.bak '1s/^.*$/new line/' *.txt

สิ่งนี้จะแทนที่บรรทัดแรกของ.txtไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันด้วยข้อความnew lineเปลี่ยนไปตามความต้องการของคุณ

ไฟล์ต้นฉบับจะถูกสำรองด้วย.bakส่วนขยายหากคุณไม่ต้องการให้ใช้:

sed -i '1s/^.*$/new line/' *.txt

ขอขอบคุณ! sedเป็นสิ่งที่ฉันกำลังมองหา!
TomTsagk

@TomTsagk ดีใจที่ฉันสามารถช่วย :)
heemayl

11

ดีใช้vimเอง:

vim -Nesc 'bufdo call setline(1,"This is the replacement.") | wq' file1 file2 ...

สิ่งนี้ทำอะไร:

  • setline (n, text)ดีเป็นฟังก์ชั่นที่ชุดสายไปntext
  • call จำเป็นต้องเรียกใช้ฟังก์ชัน
  • bufdo ถูกใช้เพื่อทำซ้ำคำสั่งข้ามบัฟเฟอร์ (โดยไม่มีช่วงจะทำหน้าที่กับบัฟเฟอร์ทั้งหมด)
  • wqบันทึกและออกจากบัฟเฟอร์ เราจำเป็นต้องทำเช่นนี้ก่อนที่จะย้ายไปยังบัฟเฟอร์ต่อไปเพื่อให้คำสั่งนี้จะถูกล่ามโซ่ไว้กับคำสั่งการใช้call|
  • -c cmdrun cmdเป็นคำสั่งโหมดคำสั่งหลังจากโหลดบัฟเฟอร์แรก
  • Nes เปิดใช้โหมดที่ไม่รองรับโหมดเงียบซึ่งไม่รองรับการประมวลผลที่ไม่โต้ตอบ

ประโยชน์ที่ได้รับ:

  • setlineเนื้อหาข้อความสามารถเป็นอะไรก็ได้ - ค่า&ในsedข้อความแทนที่สามารถมีผลกระทบที่ไม่ได้ตั้งใจ

sedดูเหมือนจะใช้งานได้ง่ายกว่า แต่มันยอดเยี่ยมจริงๆที่vimสามารถทำเช่นเดียวกัน! ขอบคุณมากสำหรับคำตอบของคุณ!
TomTsagk

@ TomTsagk ดีฉันแค่ต้องการแสดงให้เห็นว่าคุณสามารถทำงานกับหลาย ๆ ไฟล์ได้อย่างไร ( bufdo) พิจารณาคุณมีไฟล์ที่มีอยู่แล้วเปิดและ ... 1s/foo/bar/และเพื่อแสดงสลับกันไป
muru

Awesoming !!! <3_ <3
Campa

3

ตัวเลือกอื่น ๆ :

  • awk(ต้องการ GNU รุ่นที่ค่อนข้างใหม่awk)

    $ awk -i inplace -vline="new line" '(FNR==1){print line; next}1;' *.txt
    
  • Perl / เปลือก

    $ for f in *txt; do
        perl -i -lne '$.==1 ? print "new line" : print' "$f"
      done
    
  • เชลล์ / coreutils

    $ for f in *txt; do 
        ( echo "new line"; tail -n+2 "$f" ) > foo && mv foo "$f"; 
      done
    

2

สคริปต์นี้จะทำตามที่คุณร้องขอโดยวางไฟล์ที่เปลี่ยนแปลงในไดเรกทอรีใหม่โดยไม่ต้องเปลี่ยนต้นฉบับ

d=/tmp/cooked
mkdir $d
for f in *  #will match all files in current directory; adjust as desired
do
  echo "This is the new 1st line" > /${d}/${f}
  sed 1d ${f} >> /${d}/${f}
done

ฉันตอบช้า (ทดสอบรหัสของฉัน) ... และฉันชอบโซลูชันของ heemayl ดีกว่ามาก!
Charles Boling

0

การใช้ gawk

gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt

ตัวอย่าง

% cat foo.txt 
1
2
3
4

% cat bar.txt 
1
2
3
4

% gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt

% cat foo.txt                                                    
your_replacement
2
3
4

% cat bar.txt                                                    
your_replacement
2
3
4

0

jEdit: ฉันใช้เพื่อการค้นหาและแทนที่โดยรวม มันทรงพลังด้วยความสามารถในการใช้ RegEx - นิพจน์ปกติ คุณสามารถทำงานกับไฟล์ภายในไดเรกทอรีระบุนามสกุลไฟล์เช่น ".html" เป็นต้น และคุณสามารถดูสถานที่ของการเปลี่ยนแปลงตัวเลือกในบริบทใน GUI jEdit ยอดเยี่ยม

jEdit มีให้บริการผ่านทางศูนย์ซอฟต์แวร์ของ Ubuntu


0

คำสั่ง tail และ cat จะทำสิ่งนี้ได้อย่างง่ายดาย:

tail -n +1 $file > tmpfile
cat newfirstline tmpfile >$file

ล้อมรอบผู้ที่อยู่ในลูปที่เหมาะสมและอาจใช้ไฟล์ชั่วคราวที่เหมาะสมและถูกต้องแทนที่จะใช้ชื่อไฟล์ชั่วคราวที่กำหนดโค้ดยาก ฉันเชื่อว่า bash และ shell อื่น ๆ มีไวยากรณ์สำหรับสร้างไฟล์ชั่วคราว

อ็อพชัน -n ของ tail มีการตีความสองแบบขึ้นอยู่กับว่าอาร์กิวเมนต์มีเครื่องหมายบวก หากมีเครื่องหมายบวกแสดงว่าส่วนท้ายของไฟล์เริ่มต้นที่หมายเลขบรรทัดที่กำหนด มิฉะนั้นตัวเลขคือจำนวนบรรทัดรวมถึงบรรทัดสุดท้ายส่วนท้ายนั้นควรส่งออก

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