ファイルに行がない場合は、どのようにファイルに複数の行を追加できますか?

ファイルに行がない場合は、どのようにファイルに複数の行を追加できますか?

ファイルに行がない場合は、どのようにファイルに複数の行を追加できますか?

たとえば、複数のグローバルエイリアスを追加するには、/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をに追加する簡単なシェルスクリプトですdatafilenewdataこの文書を変更するのは簡単です。これは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-qgrep


では、より効率的に任意の行を配列のキーとして処理できる必要がありますawkawk

$ 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

おすすめ記事