問題のファイルに複数行を追加する方法OPは、シェル内のファイルに複数の行を追加する方法を探しています。解決策:
cat <<EOT >> test.txt
line 1
line 2
EOT
前に行を追加したいです。私の試みは次のとおりです。
echo 3 >test.text
cat test.text <<EOT >> test.text
1
2
EOT
ただし、これによりエラーが発生します。
cat: test.text: input file is output file
編集する:わかりやすくするために、設定ファイルを手動で編集する方法についての指示を含む長いサーバー設定ガイドに従っています。編集タスクには、ファイルにテキストブロックを追加するタスクが含まれることもあります。特定の手順を自動化するときは、ガイドのテキストをそのままコピーしてbashを1行に入れて、コマンドの詳細を維持したいと思います。したがって、EOT
複数行のテキスト入力が好ましい。
編集する:sedを使用する他の答えは、各行の最後にバックスラッシュを追加するように要求しますが、変更せずに複数行を入力したいと思います。
上記と同様に、ファイルの前に複数行を追加する方法はありますか(理想的には一時ファイルやインストールなしmoreutils
)。
答え1
最も安全な方法は、元のファイルを一時的な場所にコピーし、新しいコンテンツを古い名前のファイルに関連付けることです。
tmpfile=$(mktemp)
cp myfile "$tmpfile" &&
cat - "$tmpfile" <<NEW_CONTENTS >myfile
this is
new contents
at top of file
NEW_CONTENTS
rm "$tmpfile"
cat
コマンド自体は次のとおりです。ほぼあなたと同じです
cat myfile <<EOT >>myfile
1
2
3
EOT
ただし、cat
ファイル名オペランドの1つがある場合は、標準入力を読み取るように指示する必要があります-
。また、元のファイルからリダイレクトし、結果を同じファイルに追加することはできません。これは、ファイルがパーティション内のすべてのスペースを埋めるまで大きくなるループを作成するためです。そのため、最初にファイルを一時ファイルにコピーし、それを使用して古い名前の新しいコンテンツを作成しました。
私たちもこれができます。
tmpfile=$(mktemp)
cat - myfile <<NEW_CONTENTS >"$tmpfile" &&
this is
new contents
at top of file
NEW_CONTENTS
mv "$tmpfile" myfile
つまり、結果を一時ファイルに書き込み、それを移動して元のファイルを置き換えます。ただし、これらの一連の操作は所有権と権限の維持を保証しませんmyfile
。
標準入力を受け取り、与えられたファイル名の先頭に置く小さなシェル関数:
paste_header () {
local tmpfile=$(mktemp)
trap "rm -f '$tmpfile'" EXIT
cat - "$1" >"$tmpfile" &&
cat "$tmpfile" >"$1"
}
たとえば、これらの書き込み方法を使用すると、ユーザーはクリップボードの内容をインタラクティブに貼り付けることができますが、入力が中断された場合は元のファイルを変更しませんCtrl+C。Ctrl+D(送信EOT
、つまりテキストの終わり)を押して対話型入力を終了する必要があります。
この機能は次のように使用されます。
paste_header filename
追加したいデータをインタラクティブに貼り付けますfilename
(入力を終了するためCtrl+D)。
または
paste_header filename <otherfile
他のファイルのデータを挿入します。
答え2
コマンドの出力を読む必要がある場合は、リンクされたed
質問の方法を次のバリエーションで使用できます。
ed -s test.txt <<< $'0r !echo stuff\nw\nq'
これは、ゼロ行の後にr
コマンドの出力をecho stuff
記録します。test.txt
here-docを介して最初の行の前に複数行のテキストを挿入するには、次のように実行する必要があります。
ed -s test.txt <<EOT
1i
add some line
and some more
to the beginning
.
w
q
EOT
点は入力パターンの終わりを示します。つまり、最後の解決策では、テキストに単一点で構成される線が含まれていないと仮定します。
答え3
普通のものが使えます元のテキストエディタほとんどすべてのPOSIX互換システムで使用できます。
最初の行を挿入するには:
ex -sc '1i|new first line' -cx test.txt
複数の行を追加する場合は、ループに行を追加し、一番上の要素を最後に追加します(スタックのように)。
for number in 5 4 3 2 1; do
ex -sc '1i|'"$number"'' -cx newfile
done
ファイルに何度も書き込むのを避けるには、複数行の内容から変数を設定して直接挿入します。
multiple_lines=$'line1\nline2\nline3\nline4\nline5\n'
ex -sc '1i|'"$multiple_lines"'' -cx newfile
答え4
sedを使用してください:
$ sed -e 'i1' -e 'i2' test.text
1
2
3