ファイルの先頭にテキストを挿入する方法は?


213

これまでのところ、ファイルの先頭に行を追加する方法を見つけることができましたが、それはまさに私が望んでいることではありません。例で示します

ファイル内容

some text at the beginning

結果

<added text> some text at the beginning

それは似ていますが、それで新しい行を作成したくありません...

sedできればこれでやりたいです。


ここの何かがあなたのために働きますか?stackoverflow.com/questions/54365/…-を使用する必要はありませんsed
wkl 2012年

回答:


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 / ^ / <added text> \ n /' file
jslatts

1
なぜ-iを使うのですか?人にはそれは接尾辞のためであると言います。linux.die.net/man/1/sed
endrigoantonini

-iはインプレースを意味します。-iにサフィックスを追加して、上書きではなくコピーを作成できます。-i.newは.newで終わる新しいファイルを作成しますが、-iだけでファイルを直接編集します。
Jay Kamat

3
sedは空のファイルでは機能しないことに注意してください-afaict sedは、長さが0の入力では何もすることができません。
jthill

2
このソリューションの欠点は、ファイルが空の場合にテキストが追加されないことです。
DBedrenko

41

ファイルの先頭に行を追加する場合\nは、上記の最良の解決策で文字列の最後に追加する必要があります。

最善の解決策は文字列を追加することですが、文字列を使用すると、ファイルの最後に行が追加されません。

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

27

ファイルが1行だけの場合は、次を使用できます。

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 2015

これは良い解決策です。なぜ賛成票が得られなかったのでしょうか。ここに私の良いサーがあります。また、単純なエコーではなく、なぜprintfなのでしょうか。
ychaouche

1
@ychaouche-おそらくecho、改行を追加しないようにするポータブルな方法がないためですか?
Toby Speight 2016年

私はこれを> fileコマンドに追加することでファイルに"some text at the beginning"
送り込もう

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

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

の上部にタグをfile1付けProgrammingます。

ソリューション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#246841に基づくソリューションです

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

-catコマンドのinが必要であることに注意してください(標準入力を読み取ります。詳細についてはman cat、を参照してください)。ここでは、printfステートメントの出力を(STDINに)取得し、そのファイルと一時ファイルを作成する必要があると思います。http://www.linfo.org/catの下部にある説明も参照してください。 .html

ファイルを上書きするときに確認を求められないよう-fに、mvコマンドにも追加しました。

ディレクトリを再帰するには:

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

これはパスがスペースで分割されることにも注意してください。そのためのソリューションは他にもあります(たとえば、ファイルグロビング、または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 '1s/^/your text\n/' file



3

面白くするためedに、空のファイルで作業しないという問題がないソリューションを使用します。この質問に対する他の回答と同じように、それをシェルスクリプトに入れることができます。

ed Test <<EOF
a

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

上記のスクリプトは、挿入するテキストを最初の行に追加し、最初の行と2番目の行を結合します。無効な結合によるエラーでedが終了するのを防ぐために、最初にファイルの最後に空白行を作成し、まだ存在する場合は後で削除します。

制限:<added text>が1つのピリオドと完全に等しい場合、このスクリプトは機能しません。


2

私の2セント:

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

これはスラッシュを含む文字列であっても機能します "/"


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

最初tacはファイルを逆方向​​にパイプし(最後の行を最初に)、「挿入するテキスト」が最後に表示されるようにします。2番目tacはもう一度ラップして、挿入された行が先頭になり、元のファイルが元の順序になるようにします。


1
これがトーマスの問題にどのように役立つか説明していただけますか?
John Odom

tac | tac-これがスケーラブルでない考え方の形成方法です:-(
Michael

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.