Làm thế nào để chèn một văn bản ở đầu một tập tin?


213

Cho đến nay tôi đã có thể tìm cách thêm một dòng ở đầu tệp nhưng đó không phải là chính xác những gì tôi muốn. Tôi sẽ chỉ ra nó trên một ví dụ

Nội dung tập tin

some text at the beginning

Kết quả

<added text> some text at the beginning

Nó tương tự nhưng tôi không muốn tạo bất kỳ dòng mới nào với nó ...

Tôi muốn làm điều này với sednếu có thể.


Bất cứ điều gì ở đây làm việc cho bạn? stackoverflow.com/questions/54365/ trộm - bạn không cần sử dụng sed.
wkl

Câu trả lời:


314

sed có thể hoạt động trên một địa chỉ:

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

Điều kỳ diệu 1smà bạn nhìn thấy trên mỗi câu trả lời ở đây là gì? Địa chỉ dòng! .

Bạn muốn thêm <added text>vào 10 dòng đầu tiên?

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

Hoặc bạn có thể sử dụng Command Grouping:

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

67
Để thực sự chèn một dòng mới: sed -i '1s / ^ / <đã thêm văn bản> \ n /' tệp
jslatts

1
Tại sao lại dùng -i ?? Trên người đàn ông nó nói rằng nó là hậu tố. linux.die.net/man/1/sed
endrigoantonini

-i là viết tắt của tại chỗ, bạn có thể thêm hậu tố vào -i để tạo một bản sao thay vì ghi đè. -i.new sẽ tạo một tệp mới kết thúc bằng .new, nhưng chỉ -i sẽ chỉnh sửa tệp trực tiếp.
Jay Kamat

3
Lưu ý rằng sed sẽ không hoạt động trên một tập tin trống - không thể thực hiện sed để làm bất cứ điều gì với đầu vào có độ dài 0.
jthill

2
Lỗ hổng của giải pháp này là nó không thêm văn bản nếu tệp trống.
DBedrenko

41

Nếu bạn muốn thêm một dòng ở đầu tệp, bạn cần thêm \nvào cuối chuỗi trong giải pháp tốt nhất ở trên.

Giải pháp tốt nhất sẽ thêm chuỗi, nhưng với chuỗi, nó sẽ không thêm một dòng ở cuối tệp.

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

27

Nếu tệp chỉ có một dòng, bạn có thể sử dụng:

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

Nếu nó nhiều hơn một dòng. một trong:

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

Tôi đã bao gồm cái sau để bạn biết cách thực hiện các phạm vi dòng. Cả hai đều "thay thế" điểm đánh dấu dòng bắt đầu trên các dòng bị ảnh hưởng của chúng bằng văn bản bạn muốn chèn. Bạn cũng có thể (giả sử bạn sedđủ hiện đại) sử dụng:

sed -i 'whatever command you choose' filename

để thực hiện chỉnh sửa tại chỗ.


11

Bạn có thể dùng cat -

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

6
Điều này sẽ chỉ xuất văn bản theo sau bởi nội dung của tệp, nhưng nó không sửa đổi tệp nào cả.
Adaephon

Đó là một giải pháp tốt, tôi tự hỏi tại sao nó không nhận được bất kỳ sự ủng hộ nào. Đây là của tôi, thưa ngài. Ngoài ra, tại sao printf và không phải là một tiếng vang đơn giản?
ychaouche

1
@ychaouche - có lẽ vì không có cách di động nào để ngăn chặn echothêm một dòng mới?
Toby Speight

Tôi đã thử chuyển hướng này vào một tệp bằng cách nối thêm > filelệnh, nó đã spam thiết bị đầu cuối của tôi với"some text at the beginning"
theonlygusti

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

10

Để chèn chỉ một dòng mới:

sed '1i\\'

8

Sử dụng subshell:

echo "$(echo -n 'hello'; cat filename)" > filename

5

Lưu ý rằng trên OS X sed -i <pattern> file, không thành công. Tuy nhiên, nếu bạn cung cấp tiện ích mở rộng dự phòng sed -i old <pattern> file, thì filesẽ được sửa đổi tại chỗ trong khi file.oldđược tạo. Sau đó bạn có thể xóa file.oldtrong tập lệnh của mình.


4
Hoặc tập tin sed -i ''. Sau đó, nó sẽ chỉ chỉnh sửa tại chỗ và không tạo bản sao lưu.
Harvest

Tôi đã tìm thấy macOS sed muốn một dấu chấm để chỉnh sửa tại chỗ mà không tạo bản sao lưu: sed -i. Tệp <mẫu>
Bryan

4

VẤN ĐỀ: gắn thẻ một tệp, ở đầu tệp, với tên cơ sở của thư mục mẹ.

Tức là cho

/mnt/Vancouver/Programming/file1

gắn thẻ trên cùng file1với Programming.

GIẢI PHÁP 1 - tệp không trống:

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

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

1s đặt văn bản ở dòng 1 của tập tin.

GIẢI PHÁP 2 - tệp trống hoặc không trống:

Các sedlệnh, trên, thất bại trên các tập tin trống. Đây là một giải pháp, dựa trên /superuser/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841#246841

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

Lưu ý rằng lệnh -in cat là bắt buộc (đọc đầu vào tiêu chuẩn: xem man catđể biết thêm thông tin). Ở đây, tôi tin rằng, cần phải lấy đầu ra của câu lệnh printf (tới STDIN), và đưa tệp đó vào tệp tạm thời ... Xem thêm phần giải thích ở cuối http://www.linfo.org/cat .html .

Tôi cũng đã thêm -fvào mvlệnh, để tránh bị yêu cầu xác nhận khi ghi đè lên tập tin.

Để lặp lại qua một thư mục:

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

Cũng lưu ý rằng điều này sẽ phá vỡ các đường dẫn có khoảng trắng; có những giải pháp, ở những nơi khác (ví dụ như tập tin toàn cầu, hoặc find . -type f ...giải pháp -type) cho những giải pháp đó.

ĐỊA CHỈ: Re: bình luận cuối cùng của tôi, tập lệnh này sẽ cho phép bạn lặp lại các thư mục có khoảng trắng trong đường dẫn:

#!/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

Xin chào với xe trở về:

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

3

Để thêm một dòng vào đầu tệp:

sed -i '1iText to add\'

Điều này bao gồm một dòng mới, mà người hỏi rõ ràng không muốn.
Toby Speight

Cảm ơn đã cho tôi chính xác những gì tôi cần
FindOutIslamNow

3

Có một cách rất dễ dàng:

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

Ow ... xin lỗi, bây giờ tôi nhận ra rằng bạn muốn thêm vào lúc đầu và không phải là một dòng mới.
Biệt thự Raphael Boas

Nhưng tôi muốn một dòng mới. Vì vậy, cảm ơn cho cách tiếp cận đơn giản.
TheSatinKnight

3

Để cho vui, đây là một giải pháp sử dụng edmà không có vấn đề gì khi không làm việc trên một tệp trống. Bạn có thể đặt nó vào một tập lệnh shell giống như bất kỳ câu trả lời nào khác cho câu hỏi này.

ed Test <<EOF
a

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

Kịch bản trên thêm văn bản để chèn vào dòng đầu tiên, sau đó nối dòng thứ nhất và thứ hai. Để tránh ed thoát khỏi lỗi với phép nối không hợp lệ, trước tiên, nó tạo một dòng trống ở cuối tệp và xóa nó sau nếu nó vẫn tồn tại.

Hạn chế: Tập lệnh này không hoạt động nếu <added text>chính xác bằng một khoảng thời gian duy nhất.


2

theo quan điểm của tôi:

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

Điều này sẽ làm việc ngay cả là chuỗi chứa dấu gạch chéo "/"


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

Đầu tiên tacđặt tệp ngược lại (dòng cuối cùng trước) để "văn bản cần chèn" xuất hiện sau cùng. Cái thứ 2 tacbọc nó một lần nữa để dòng được chèn ở đầu và tệp gốc theo thứ tự ban đầu.


1
Bạn có thể vui lòng giải thích làm thế nào điều này sẽ giúp Tomas với vấn đề này?
John Odom

tấc | tac - đó là cách mà những tư duy không thể mở rộng hình thành :-(
Michael Shigorin

0

Một giải pháp khác với bí danh. Thêm vào tập tin init RC / env của bạn:

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

Sử dụng:

addtail "string to add at the beginning of file"
addtail "string to add at the end of file"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.