วิธีแทรกข้อความก่อนบรรทัดแรกของไฟล์?


76

ฉันได้ดูรอบ ๆsedคำสั่งเพื่อเพิ่มข้อความลงในไฟล์ในบรรทัดเฉพาะ งานนี้เพิ่มข้อความหลังบรรทัด 1:

sed '1 a\

แต่ฉันต้องการเพิ่มก่อนบรรทัด 1 มันจะเป็น:

sed '0 a\

invalid usage of line address 0แต่ฉันได้รับข้อผิดพลาดนี้:

ข้อเสนอแนะใด ๆ


คำตอบ:


101

ใช้ตัวเลือกการsedแทรก ( i) ซึ่งจะแทรกข้อความในบรรทัดก่อนหน้า

sed '1 i\

อัปเดตคำถามของผู้เขียน:

เพื่อให้แก้ไขไฟล์ในสถานที่ - ด้วย GNU sed- ฉันต้องเพิ่ม -iตัวเลือก:

sed -i '1 i\anything' file

นอกจากนี้ไวยากรณ์

sed  -i '1i text' filename

สำหรับผู้ที่ไม่ใช่ GNU

คุณต้องกดปุ่มย้อนกลับทันทีหลังแบ็กสแลช1i\และหลังfirst_line_text:

sed -i '1i\
first_line_text
'

นอกจากนี้โปรดทราบว่าการใช้งานที่ไม่ใช่ของ GNU sed(ตัวอย่างเช่นหนึ่งใน macOS) จำเป็นต้องมีอาร์กิวเมนต์สำหรับการ-iตั้งค่าสถานะ (ใช้-i ''เพื่อให้ได้ผลเช่นเดียวกับ GNU sed)


1
มันไม่ทำงานหากไม่มี-iตัวเลือก ฉันจะอัปเดตคำตอบของคุณก่อนที่จะยอมรับ
Manolo

1
ขอบคุณ คุณใช้ระบบปฏิบัติการอะไร? โซลูชันดั้งเดิมทำงานบน OpenSuse 9.
suspectus

1
ที่น่าสนใจ! ฉันใช้ Lubuntu 13.10 และใช้sed '1 i\this text is entered above the existing first line' fileงานได้สำหรับฉัน

2
ที่นี่ใช้งานได้sed (GNU sed) 4.2.2แค่ sed '1 i text to insert' -i fileมีเสน่ห์ ขอบคุณ
ตัน

1
@FeRD ดูawkคำตอบที่ไม่ดีอันดับของฉันด้านล่าง สิ่งนี้น่าจะใช้ได้
rudimeier

18

Echo ใช้เพื่อรับข้อความ ชื่อไฟล์ Cat - พิมพ์ไฟล์ในคอนโซลและ> ใช้เพื่อส่งไปยังไฟล์ชื่อไฟล์ 1 อีกครั้งจากนั้นเราย้ายชื่อไฟล์ 1 ไปยังชื่อไฟล์เพื่อให้ข้อความแทรกลงในบรรทัดแรกของไฟล์ที่ต้องการ

  (echo "some text" && cat filename) > filename1 && mv filename1 filename

7
โปรดแจ้งให้เราทราบว่าเหตุใด downvote ต่อไปนี้
Ankit Shah

1
อาจเป็นเพราะ OP กล่าวถึง ที่ไม่สมควรลงคะแนนในความคิดของฉัน ทางออกนั้นเป็นสิ่งที่เหมาะสมที่สุดกับความต้องการของฉัน
рüффп

ฉันโหวตขึ้น ทำงานบน ksh สำหรับฉัน
arcee123

16

คุณสามารถใช้ Vim ในโหมด Ex:

ex -sc '1i|ALFA BRAVO' -cx file
  1. 1 เลือกบรรทัดแรก

  2. i แทรกข้อความและขึ้นบรรทัดใหม่

  3. x บันทึกและปิด


7

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

sed '1 i\
your_text' your_file

เอกสารที่นี่ยังสามารถช่วย:

cat /dev/stdin your_file <<EOI
Your text
goes here
EOI

6

ใช้ GNU awk> = 4.1:

awk -i inplace 'BEGINFILE{print "first line"}{print}' foo.sh

ตรงข้ามกับsedคำตอบทั้งหมดการทำงานกับไฟล์เปล่าเช่นกัน


inplaceเป็นห้องสมุดและน่าเสียดายที่มันปรากฏในการแจกแจง awk ทั้งหมดที่จัดส่ง ฉันได้รับ "awk: ร้ายแรง: ไม่สามารถเปิดไฟล์ 'inplace' เพื่ออ่าน" GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.1, GNU MP 6.1.2)
ซอร์สได้

6
sed  -i '1i new_text' file_name

หากคุณไม่ได้ระบุ-iตัวเลือกมันจะไม่แสดงข้อผิดพลาดใด ๆ และแสดงผลลัพธ์บนเทอร์มินัลมาตรฐาน แต่ไม่ได้แทรกข้อความในไฟล์


คำถามไม่ได้เกี่ยวกับ-iสวิตช์
don_crissti

คุณคิดยังไง มันเป็นคำตอบสำหรับคำถาม ใช่มันคล้ายกับคำตอบที่ยอมรับ แต่ไม่เหมือนกันทั้งหมด
G-Man

@ G-Man - หนึ่งอาจจะเถียงแม่แบบที่ใช้โดย CAS อยู่ไกลจากอุดมคติ แต่จริงๆนี้เป็นคล้ายเหมือนในเกือบเหมือน ... ที่แตกต่างกันเป็นระยะห่างและความจริงที่คนนี้ไม่เคยมีใครทับขวา เท่าที่ฉันเป็นห่วงพวกเขาจะเหมือนกันในทางเทคนิค (เพราะทั้งคู่มีความgnu sedเฉพาะเจาะจงและมันเกิดขึ้นที่gnu sedจะยอมรับiโดยไม่มีเครื่องหมายแบ็กสแลช) ถ้าคนอื่นคิดว่านี่รับประกันคำตอบที่แยกต่างหาก
don_crissti

2

0aคำสั่งที่คุณพยายามที่จะทำงานในexบรรพบุรุษเพื่อvi :

printf '%s\n' 0a 'Anything you want to add' . x | ex file.txt

printfคำสั่งด้วยตัวเองเอาท์พุท:

0a
Anything you want to add
.
x

0aวิธีการผนวกหลังจากบรรทัด 0 (คือก่อนบรรทัดแรก)

บรรทัดถัดไปหรือหลายบรรทัดเป็นข้อความตัวอักษรที่จะเพิ่ม

.บนเส้นด้วยตัวเองยุติ "การผนวกคำสั่ง"

xสาเหตุที่ไม่ได้รับสิทธิในการบันทึกการเปลี่ยนแปลงไปยังแฟ้มและทางออก


1

ฉันประหลาดใจที่ในคำถามเก่านี้ไม่มีใครแสดงคำสั่ง sed (และง่ายมากในกรณีนี้) สามัญที่สุด:

$ sed  -i '1s/^/new_text\
/' file_name

ซึ่งใช้งานได้กับหอยส่วนใหญ่และสามารถพกพาไปได้หลายรุ่น
หาก GNU sed พร้อมใช้งานคุณสามารถใช้สิ่งนี้:

$ sed -i '1s/^/new_text\n' file_name

ความแตกต่างคือ GNU sed อนุญาตให้ใช้ a \nสำหรับ newline และอื่น ๆ จำเป็นต้องขึ้นบรรทัดใหม่ตามตัวอักษรด้วย backslash (ซึ่งทำงานใน GNU sed อยู่ดี)

หากเชลล์ที่ยอมรับการ$'…'ใช้งานไวยากรณ์คุณสามารถแทรกขึ้นบรรทัดใหม่ได้โดยตรงดังนั้น sed จะเห็นว่ามีการขึ้นบรรทัดใหม่แล้ว:

$ sed -i $'1s/^/new_text\\\n/' file_name

ซึ่งใช้งานได้กับรุ่น sed มากขึ้น


-1

น่าเสียดายที่คำตอบทั้งหมดข้างต้น (ส่วนใหญ่มีsed) ไม่ได้ผลสำหรับฉันเพราะพวกเขาทั้งหมดแทนที่บรรทัดแรก ฉันอยู่บนUbuntu 16.04 LTSเครื่อง นี่คือวิธีแก้ปัญหาของฉันด้วยGNU Awk 4.0.2:

awk '{if(NR==1){$0="NEW_FIRST_LINE"$0; print $0} ;if(NR!=1){print $0}}' file_name

1
ไม่แน่ใจว่าคุณกำลังพูดถึงอะไร ... มีเพียงsedคำตอบเดียวที่ใช้การแทนที่ แต่ไม่ได้แทนที่บรรทัดที่มีอยู่
don_crissti

-1

ครั้งแรกและครั้งสุดท้าย

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

cal |                            \
  gsed -E                        \
       -e     '1i\{'             \
       -e     '1i\  "lines": ['  \
       -e 's/(.*)/    "\1",/'    \
       -e '$s/,$//'              \
       -e     '$a\  ]'           \
       -e     '$a\}'

คำอธิบาย

นี่เป็นcalเอาต์พุตที่ส่งไปยัง gnu- sed(เรียกว่าgsedบน macOS ที่ติดตั้งผ่านbrew.sh ) พร้อมกับขยาย RegEx ( -E) และ 6 "สคริปต์" ถูกนำไปใช้ ( -e) และตัวแบ่งบรรทัดหนีออกมา\เพื่อความสะดวกในการอ่าน สคริปต์ 1 & 2 ใช้1i\เพื่อ "ที่บรรทัด 1, แทรก" สคริปต์ 5 & 6 ใช้$a\เพื่อ "at line <last>, ผนวก" ฉันจัดแนวเอาท์พุทข้อความในแนวตั้งเพื่อให้โค้ดแสดงสิ่งที่คาดหวังในผลลัพธ์ สคริปต์ 3 และ 4 ทำการทดแทน (รายการหลังใช้กับ "บรรทัด <last>" เท่านั้น) ผลลัพธ์กำลังแปลงเอาต์พุตคำสั่งเป็น JSON ที่ถูกต้อง

เอาท์พุต

{
  "lines": [
    "    October 2019      ",
    "Su Mo Tu We Th Fr Sa  ",
    "       1  2  3  4  5  ",
    " 6  7  8  9 10 11 12  ",
    "13 14 15 16 17 18 19  ",
    "20 21 22 23 24 25 26  ",
    "27 28 29 30 31        ",
    "                      "
  ]
}

ในขณะที่ฉันยังไม่ได้โหวตคำถามของคุณโปรดทราบว่าเรามีคำตอบหลายข้ออยู่แล้วซึ่งรวมถึงคำตอบที่ยอมรับแล้วซึ่งแสดงให้เห็นถึงผลลัพธ์ที่ต้องการ
Jeff Schaller

@JeffSchaller ชุมชน Stack Exchange ไม่ใช่ฟอรัม จุดประสงค์ของมันครอบคลุมเกินกว่าที่จะช่วยให้ OP ได้รับการปลดล็อค เป้าหมายคือการสร้างฐานความรู้ระดับโลกพร้อมตัวเลือกมากมายที่ผู้ค้นหาสามารถสะดุดเมื่อค้นหาคำตอบ เหตุผลที่ฉันตั้งชื่อคำตอบของฉันคือเพื่อช่วยให้ผู้ใช้รู้จักประโยชน์ของคำตอบนี้ก่อนที่จะคลิกผลลัพธ์ของ Google
Bruno Bronosky

สิ่งที่ฉันพูดคือคำตอบของคุณไม่มีตัวเลือกใหม่ (คำตอบ) สำหรับผู้อ่านในอนาคตของคำถามนี้ เรามีสี่คำตอบที่ใช้รูปแบบของ1iการแทรกข้อความก่อนบรรทัดแรก บางคนที่มีคำถามนี้จะต้องแยกส่วนที่พวกเขาต้องการจากคำตอบของคุณเพื่อแก้ปัญหาของพวกเขา คำถามฟรีดังนั้นฉันขอเชิญคุณถามและตอบคำถามของคุณเองเพื่อให้คำตอบเฉพาะของคุณ
Jeff Schaller
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.