ファイルに行がない場合は、どのようにファイルに複数の行を追加できますか?
たとえば、複数のグローバルエイリアスを追加するには、/etc/bash.bashrc
次のようにします。ここのドキュメント:
cat <<-"BASHRC" >> /etc/bash.bashrc
alias rss="/etc/init.d/php*-fpm restart && systemctl restart nginx.service"
alias brc="nano /etc/bash.bashrc"
BASHRC
このタスクには、行がすでに存在するかどうかを確認する方法は含まれておらず、誤ってこの文書を再実行すると重複と競合が発生する可能性があるという批判を受けました。
ベストアンサー1
ファイルの行newdata
をに追加する簡単なシェルスクリプトですdatafile
。newdata
この文書を変更するのは簡単です。これはgrep
、すべての(新しい)入力ラインが必要なため、実際には非常に効率的ではありません。
target=datafile
while IFS= read -r line ; do
if ! grep -Fqxe "$line" "$target" ; then
printf "%s\n" "$line" >> "$target"
fi
done < newdata
各行に対してこれを使用して、固定文字列の一致(正規表現なし)、完全な行の一致、および一致する行の出力を抑制するためにターゲットgrep
ファイルにすでに存在することを確認します。一致する行がない場合は偽のエラーコードが返されるので、否定的な結果が真の場合はターゲットファイルに追加してください。-F
-x
-q
grep
では、より効率的に任意の行を配列のキーとして処理できる必要がありますawk
。awk
$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata
最初の部分は、FNR == NR { lines[$0] = 1; next }
最初の入力ファイルのすべての行を(関連付け)配列のキーとしてロードしますlines
。 2番目の部分は! ($0 in lines) {print}
次の入力ラインで動作し、そのラインが配列にない場合は「新しい」ラインを印刷します。
生成された出力には新しい行のみが含まれるため、元のファイルに追加する必要があります。例sponge
:
$ awk 'FNR == NR { lines[$0] = 1; next } ! ($0 in lines) {print}' datafile newdata | sponge -a datafile
または、awk
次の行を最後の行に追加することもできます。これを行うには、ファイル名を次のように渡しますawk
。
$ target=datafile
$ awk -vtarget="$target" 'FNR == NR { lines[$0] = 1; next }
! ($0 in lines) {print >> target}' "$target" newdata
here-docを使用するには、リダイレクトの設定に加えて、awk
(stdin)を明示的なソースファイルとして追加する必要があります。-
awk ... "$target" - <<EOF