เขียนไปยังไฟล์ แต่เขียนทับหากมีอยู่


252
echo "text" >> 'Users/Name/Desktop/TheAccount.txt'

ฉันจะสร้างมันอย่างไรเพื่อที่จะสร้างไฟล์หากมันไม่มีอยู่ แต่จะเขียนทับมันถ้ามันมีอยู่แล้ว ตอนนี้สคริปต์นี้เพิ่งต่อท้าย


ดี .. มันยอดเยี่ยมมาก ฉันยอมรับ> เร็วกว่า >> เล็กน้อย
Jokester

คำตอบ:


410

ความเข้าใจเล็กน้อยเกี่ยวกับวิธีการทำงานของ * nix pipes จะช่วยได้

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

echo "text" > 'Users/Name/Desktop/TheAccount.txt'

9
-bash: TheAccount.txt: cannot overwrite existing fileสภาพแวดล้อมบางอย่างไม่อนุญาตให้กับสิ่งที่ต้องการ
Tom Russell

16
นอกจากนี้>และ>>เป็นผู้ประกอบการเปลี่ยนเส้นทางการส่งออก |ประกอบท่อ
Tom Russell

22
ดูคำตอบโดย @BrDaHa ใช้>|เพื่อบังคับเขียนทับที่มีอยู่
Jake

2
นี่ไม่ใช่คำตอบที่ถูกต้องเลยเพราะมันจะไม่เขียนทับไฟล์ที่มีอยู่
iWizard

4
คำตอบควรได้รับการอัปเดตด้วยคำตอบของ @ Jake จากความคิดเห็นเหล่านี้คำตอบที่ยอมรับนั้นผิดในหลายวิธี
rm.rf.etc

90

ใน Bash หากคุณตั้งค่า noclobber a set -o noclobberแล้วคุณจะใช้ไวยากรณ์>|

ตัวอย่างเช่น:

echo "some text" >| existing_file

วิธีนี้สามารถใช้งานได้หากไฟล์ยังไม่มีอยู่


  • ตรวจสอบว่ามีการตั้งค่า noclobber ด้วย: set -o | grep noclobber

  • สำหรับคำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับตัวดำเนินการชนิดพิเศษนี้ดูโพสต์นี้

  • สำหรับรายละเอียดเพิ่มเติมของผู้ดำเนินการเปลี่ยนเส้นทางดูที่โพสต์นี้


@ กระตุ้นคุณใช้ bash shell หรือไม่
BrDaHa

@BrDaHa ฉันจะเปลี่ยนเส้นทาง stderr ด้วย> | ได้อย่างไร เช่นกัน ฉันลอง &> | แต่มันไม่ทำงาน
Tu Bui

@ TuBui ไม่แน่ใจว่าทำไมมันไม่ทำงานสำหรับคุณ บนเครื่องของฉัน&>| fileทำงาน คุณใช้เชลล์และรุ่นอะไร @ กระตุ้นให้ zsh ทั้งคู่ทำงานได้ดีเพราะทุบตีเท่านั้น>|
Griddo

@Griddo เปลือกของฉันเป็นรุ่นทุบตี 4.3.48 (1) - ปล่อย ส่งผลให้เกิดข้อผิดพลาดecho "aaa" &>| test.txt -bash: syntax error near unexpected token |noclobber ของฉันตั้งไว้ที่
Tu Bui

1
@TuBui เห็นได้ชัดว่าฉันไม่ได้ทดสอบอย่างถูกต้อง มันไม่ทำงานสำหรับฉันเช่นกัน ... อย่างไรก็ตามเอกสารไม่ได้ระบุว่าควรเป็นไปได้ คุณอาจจะต้องติดecho "aaa" >| test.txt 2>&1หรือใช้เปลือกหอยอื่น
Griddo

40

แม้จะมีNylonSmileคำตอบซึ่งก็คือ "เรียงลำดับ" ถูกต้อง .. ฉันไม่สามารถเขียนทับไฟล์ได้ในลักษณะนี้ ..

echo "i know about Pipes, girlfriend" > thatAnswer

zsh: file exists: thatAnswer

การแก้ปัญหาของฉัน .. ผมต้องใช้ ... >!, a la ..

[[ $FORCE_IT == 'YES' ]] && echo "$@" >! "$X" || echo "$@" > "$X"

เห็นได้ชัดว่าระวังด้วย ...


26
ซึ่งหมายความว่าคุณมีNOCLOBBERชุดตัวเลือก zsh ที่ไม่ใช่ค่าเริ่มต้น ใช้setopt clobber เพื่อเรียกคืนพฤติกรรมเริ่มต้น
Michał Politowski

11

หากสภาพแวดล้อมของคุณไม่อนุญาตให้เขียนทับด้วย>ให้ใช้ไพพ์|และteeแทนดังนี้:

echo "text" | tee 'Users/Name/Desktop/TheAccount.txt'

หมายเหตุสิ่งนี้จะพิมพ์ไปยัง stdout ด้วย ในกรณีที่ไม่พึงประสงค์คุณสามารถเปลี่ยนเส้นทางการส่งออก/dev/nullเป็นดังนี้:

echo "text" | tee 'Users/Name/Desktop/TheAccount.txt' > /dev/null


2

เพียงสังเกตว่าหากคุณต้องการเปลี่ยนทั้ง std :: cerr และ std :: cout ไปยังไฟล์ในขณะที่คุณมี noclobber set (เช่นset -o noclobber) คุณสามารถใช้รหัสได้:

    cmd >|file.txt 2>&1

ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้สามารถมองเห็นที่https://stackoverflow.com/a/876242

นอกจากนี้ยังมีคำถาม @ TuBui ของคำตอบสำหรับคำตอบ @BrDaHa ที่ให้ไว้ข้างต้นในวันที่ 9 ส.ค. 18 ที่ 9:34


0

หากต้องการเขียนทับเนื้อหาของไฟล์หนึ่งไปยังไฟล์อื่น ใช้แมวเช่น

echo  "this is foo" > foobar.txt
cat foobar.txt

echo "this is bar" > bar.txt
cat bar.txt

ตอนนี้เพื่อเขียนทับ foobar เราสามารถใช้คำสั่ง cat ดังต่อไปนี้

cat bar.txt >> foobar.txt
cat foobar.txt

ป้อนคำอธิบายรูปภาพที่นี่


"ตอนนี้จะเขียนทับ foobar ... " - >>กำลังจะผนวกไม่เขียนทับ
Drenai

-2

หากคุณมีเอาต์พุตที่อาจมีข้อผิดพลาดคุณอาจต้องการใช้เครื่องหมายและและมากกว่าดังนี้:

my_task &> 'Users/Name/Desktop/task_output.log' สิ่งนี้จะเปลี่ยนเส้นทางทั้ง stderr และ stdout ไปยังไฟล์บันทึก (แทนที่จะเป็น stdout เท่านั้น)


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