วิธีแทรกข้อความที่จุดเริ่มต้นของไฟล์ได้อย่างไร


213

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

เนื้อหาไฟล์

some text at the beginning

ผลลัพธ์

<added text> some text at the beginning

มันคล้ายกัน แต่ฉันไม่ต้องการสร้างบรรทัดใหม่ด้วย ...

ฉันต้องการทำสิ่งนี้ด้วยsedถ้าเป็นไปได้


มีอะไรในที่นี่ที่เหมาะกับคุณ stackoverflow.com/questions/54365/... - sedคุณไม่จำเป็นต้องใช้
wkl

คำตอบ:


314

sed สามารถทำงานกับที่อยู่:

$ sed -i '1s/^/<added text> /' file

วิเศษนี้ที่1sคุณเห็นในทุกคำตอบคืออะไร? ที่อยู่บรรทัด! .

ต้องการเพิ่ม<added text>ใน 10 บรรทัดแรกหรือไม่

$ sed -i '1,10s/^/<added text> /' file

หรือคุณสามารถใช้Command Grouping:

$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}

67
ในการแทรกบรรทัดใหม่จริง: sed -i '1s / ^ / <ข้อความที่เพิ่ม> \ n /' ไฟล์
jslatts

1
ทำไมต้องใช้ -i? เกี่ยวกับมนุษย์มันบอกว่ามันเป็นคำต่อท้าย linux.die.net/man/1/sed
endrigoantonini

-i ย่อมาจากในสถานที่คุณสามารถผนวกคำต่อท้ายเพื่อ -i เพื่อทำสำเนามากกว่าเขียนทับ -i.new จะทำให้ไฟล์ใหม่ลงท้ายด้วย. new แต่เพียงแค่ -i จะแก้ไขไฟล์โดยตรง
Jay Kamat

3
โปรดทราบว่า sed ไม่สามารถใช้งานไฟล์ที่ว่างเปล่าได้เพราะไม่สามารถทำอะไรเลยได้เลยด้วยอินพุต 0 ความยาว
jthill

2
ข้อบกพร่องของการแก้ปัญหานี้คือมันไม่ได้เพิ่มข้อความหากไฟล์ว่างเปล่า
DBedrenko

41

หากคุณต้องการเพิ่มบรรทัดที่จุดเริ่มต้นของไฟล์คุณจะต้องเพิ่ม\nที่ส่วนท้ายของสตริงในโซลูชันที่ดีที่สุดด้านบน

ทางออกที่ดีที่สุดจะเพิ่มสตริง แต่ด้วยสตริงนั้นจะไม่เพิ่มบรรทัดที่ท้ายไฟล์

sed -i '1s/^/your text\n/' file

27

หากไฟล์เป็นเพียงหนึ่งบรรทัดคุณสามารถใช้:

sed 's/^/insert this /' oldfile > newfile

ถ้ามันมากกว่าหนึ่งบรรทัด หนึ่งใน:

sed '1s/^/insert this /' oldfile > newfile
sed '1,1s/^/insert this /' oldfile > newfile

ฉันได้รวมรายการหลังเพื่อให้คุณรู้วิธีการทำช่วงของเส้น ทั้งสอง "แทนที่" ตัวทำเครื่องหมายบรรทัดเริ่มต้นในบรรทัดที่ได้รับผลกระทบด้วยข้อความที่คุณต้องการแทรก คุณสามารถใช้ (สมมติว่าคุณsedทันสมัยพอ) ใช้:

sed -i 'whatever command you choose' filename

เพื่อทำการแก้ไขในสถานที่


11

คุณสามารถใช้ได้ cat -

printf '%s' "some text at the beginning" | cat - filename

6
สิ่งนี้จะส่งออกข้อความตามด้วยเนื้อหาของไฟล์เท่านั้น แต่จะไม่แก้ไขไฟล์เลย
Adaephon

นั่นเป็นทางออกที่ดีฉันสงสัยว่าทำไมมันถึงไม่ได้ upvotes นี่คือของฉันที่ดีของฉัน นอกจากนี้ทำไม printf และไม่ใช่เสียงสะท้อนอย่างง่าย?
ychaouche

1
@ychaouche - น่าจะเป็นเพราะไม่มีวิธีพกพาในการป้องกันechoการเพิ่มขึ้นบรรทัดใหม่?
Toby Speight

ฉันพยายามนำสิ่งนี้ไปเป็นไฟล์โดยต่อท้าย> fileคำสั่งมันก็แค่สแปมเทอร์มินัลด้วย"some text at the beginning"
theonlygusti

2
printf '%s' "some text" | cat - filename > tmpfile && mv tmpfile filename
ลู

10

หากต้องการแทรกเพียงขึ้นบรรทัดใหม่:

sed '1i\\'


5

โปรดทราบว่าใน OS X sed -i <pattern> file,, ล้มเหลว แต่ถ้าคุณให้ขยายการสำรองข้อมูลsed -i old <pattern> fileแล้วfileมีการแก้ไขในขณะที่file.oldถูกสร้างขึ้น จากนั้นคุณสามารถลบfile.oldในสคริปต์ของคุณ


4
หรือไฟล์ sed -i '' จากนั้นจะแก้ไขได้ทันทีและไม่ทำการสำรองข้อมูล
Harv

ฉันพบว่า macOS sed ต้องการจุดที่จะแก้ไขโดยไม่ต้องสร้างการสำรองข้อมูล: sed -i ไฟล์ <รูปแบบ>
ไบรอัน

4

ปัญหา:แท็กไฟล์ที่ด้านบนของไฟล์ด้วยชื่อฐานของไดเรกทอรีหลัก

เช่นสำหรับ

/mnt/Vancouver/Programming/file1

แท็กด้านบนของที่มีfile1Programming

โซลูชัน 1 - ไฟล์ที่ไม่ว่าง:

bn=${PWD##*/}    ## bn: basename

sed -i '1s/^/'"$bn"'\n/' <file>

1s วางข้อความที่บรรทัด 1 ของไฟล์

โซลูชัน 2 - ไฟล์เปล่าหรือไฟล์ไม่ว่าง:

sedคำสั่งข้างต้นล้มเหลวในไฟล์ที่ว่างเปล่า นี่คือวิธีแก้ไขตาม/superuser/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841/how-do-i

printf "${PWD##*/}\n" | cat - <file> > temp && mv -f temp <file>

โปรดทราบว่า-จำเป็นต้องใช้คำสั่ง in ในคำสั่ง cat (อ่านอินพุตมาตรฐาน: ดูman catข้อมูลเพิ่มเติม) ที่นี่ฉันเชื่อว่ามันเป็นสิ่งจำเป็นที่จะใช้เอาท์พุทของคำสั่ง printf (เพื่อ STDIN) และ cat ที่และไฟล์ที่จะ temp ... ดูคำอธิบายที่ด้านล่างของhttp://www.linfo.org/cat .html

ฉันยังเพิ่ม-fไปยังmvคำสั่งเพื่อหลีกเลี่ยงการถูกถามยืนยันเมื่อเขียนทับไฟล์

ในการเรียกคืนไปยังไดเรกทอรี:

for file in *; do printf "${PWD##*/}\n" | cat - $file > temp && mv -f temp $file; done

โปรดทราบว่าสิ่งนี้จะทำลายเส้นทางที่มีช่องว่าง มีวิธีแก้ไขปัญหาที่อื่น (เช่นไฟล์ globbing หรือfind . -type f ...- ประเภทโซลูชั่น) สำหรับผู้ที่

เพิ่ม: Re: ความคิดเห็นล่าสุดของฉันสคริปต์นี้จะช่วยให้คุณสามารถชดเชยไดเรกทอรีที่มีช่องว่างในเส้นทาง:

#!/bin/bash

## /programming/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi

## To allow spaces in filenames,
##   at the top of the script include: IFS=$'\n'; set -f
##   at the end of the script include: unset IFS; set +f

IFS=$'\n'; set -f

# ----------------------------------------------------------------------------
# SET PATHS:

IN="/mnt/Vancouver/Programming/data/claws-test/corpus test/"

# /superuser/716001/how-can-i-get-files-with-numeric-names-using-ls-command

# FILES=$(find $IN -type f -regex ".*/[0-9]*")        ## recursive; numeric filenames only
FILES=$(find $IN -type f -regex ".*/[0-9 ]*")         ## recursive; numeric filenames only (may include spaces)

# echo '$FILES:'                                      ## single-quoted, (literally) prints: $FILES:
# echo "$FILES"                                       ## double-quoted, prints path/, filename (one per line)

# ----------------------------------------------------------------------------
# MAIN LOOP:

for f in $FILES
do

  # Tag top of file with basename of current dir:
  printf "[top] Tag: ${PWD##*/}\n\n" | cat - $f > temp && mv -f temp $f

  # Tag bottom of file with basename of current dir:
  printf "\n[bottom] Tag: ${PWD##*/}\n" >> $f
done

unset IFS; set +f


3

ในการเพิ่มบรรทัดไปยังด้านบนของไฟล์:

sed -i '1iText to add\'

ซึ่งรวมถึงการขึ้นบรรทัดใหม่ซึ่งผู้ถามไม่ต้องการอย่างชัดเจน
Toby Speight

ขอบคุณที่ให้สิ่งที่ฉันต้องการกับฉันอย่างแน่นอน
FindOutIslamNow

3

มีวิธีง่าย ๆ :

echo "your header" > headerFile.txt
cat yourFile >> headerFile.txt

ขออภัย ... ตอนนี้ฉันรู้แล้วว่าคุณต้องการเพิ่มที่จุดเริ่มต้นไม่ใช่บรรทัดใหม่
Raphael Villas Boas

แต่ฉันต้องการบรรทัดใหม่ ขอบคุณมากสำหรับวิธีการที่ง่าย
TheSatinKnight

3

เพื่อความสนุกนี่คือวิธีแก้ปัญหาการใช้งานedที่ไม่มีปัญหาในการไม่ทำงานกับไฟล์เปล่า คุณสามารถใส่มันลงในเชลล์สคริปต์เหมือนกับคำตอบอื่น ๆ ของคำถามนี้

ed Test <<EOF
a

.
0i
<added text>
.
1,+1 j
$ g/^$/d
wq
EOF

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

ข้อ จำกัด :สคริปต์นี้ใช้ไม่ได้หาก<added text>เท่ากับระยะเวลาเดียว


2

สองเซ็นต์ของฉัน:

sed  -i '1i /path/of/file.sh' filename

สิ่งนี้จะทำงานได้แม้จะเป็นสตริงที่มีเครื่องหมายสแลช "/"


1
echo -n "text to insert " ;tac filename.txt| tac > newfilename.txt

แรกtacไพพ์ไฟล์ย้อนหลัง (บรรทัดสุดท้ายก่อน) ดังนั้น "text to insert" จะปรากฏขึ้นครั้งสุดท้าย ส่วนที่ 2 tacจะแรปอีกครั้งเพื่อให้บรรทัดที่แทรกอยู่ที่จุดเริ่มต้นและไฟล์ต้นฉบับอยู่ในลำดับเดิม


1
คุณกรุณาอธิบายว่าสิ่งนี้จะช่วยโทมัสได้อย่างไร
John Odom

tac | tac - นั่นคือรูปแบบความคิดที่ไม่สามารถปรับขนาดได้แบบ :-(
Michael Shigorin

0

โซลูชันอื่นที่มีชื่อแทน เพิ่มลงในไฟล์ init rc / env ของคุณ:

addtail () { find . -type f ! -path "./.git/*" -exec sh -c "echo $@ >> {}" \; }
addhead () { find . -type f ! -path "./.git/*" -exec sh -c  "sed -i '1s/^/$@\n/' {}" \; }

การใช้งาน:

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