Recherches ocurrences dans les dernières lignes

Quand tu écris “mv”, ça va écraser le fichier définitif ?

awk "NR<10||NR>20" fichier > fichier2 && mv fichier2 fichier

Pour mon exemple, même s’il y a des moyens plus efficaces ou plus courts, je veux me faire un mini script qui supprime les “Explanations…” du fichier preferences.
Je sais que ce dernier s’arrête à la ligne 53 et qu’ensuite viennent les paquets qui ont été placés là par ma réponse § lors de l’upgrade, genre :

Explanation: Pinned by apt-listbugs at Sat Oct 22 01:11:23 +0200 2011 Explanation: #642572: liblucene2-java: cross dependencies prevent the installation of eclipse-cdt Package: liblucene2-java Pin: version 2.9.4+ds1-2 Pin-Priority: 1000
Parfois, il y en a plusieurs et même beaucoup, donc avant de refaire une MAJ la semaine suivante, je supprime ces “exclus” car en général, la plupart ont été guéris.
Je me refais donc un preferences propre.
Mon script serait :

awk "NR<54" /etc/apt/preferences > /etc/apt/pref-relais && mv /etc/apt/pref-relais /etc/apt/preferences

Je suppose que la commande doit être agrémenté d’un “sudo”.

EDIT :
Ça fonctionne parfaitement :023

Et ça ça marche ?

Ça serait plus fiable je pense (tu ne pars pas de l’hypothèse que ton fichier de préférence fait 53 lignes).

Oui, tu as raison pour le cas où ça serait un tuto mais ici, il s’agit d’un truc perso et je suis sûr des N° de lignes et j’ai une marge supplémentaire

... 49 Package: * 50 Pin: release o=Boisson,c=divers 51 Pin-Priority:490 52 53 ########################################################################################### 54 55

Mais j’ai un autre problème : j’ai fait le test sur un montage maison mais en réel, il n’admet pas directement sudo pour écrire :open_mouth:

ricardo@sid-sda8:~$ sudo awk "NR<54" /etc/apt/preferences > /etc/apt/pref-relais && mv /etc/apt/pref-relais /etc/apt/preferences bash: /etc/apt/pref-relais: Permission non accordée
Si je place pref-relais dans ~/, il me demande confirmation pour écraser et refuse quand même :

mv : voulez-vous écraser « /etc/apt/preferences » en outrepassant le mode 0644 (rw-r--r--) ? o mv: échec de déplacement inter-périphérique de « /home/ricardo/Documents/pref-relais » vers « /etc/apt/preferences » ; impossible de supprimer la cible: Permission non accordée

EDIT : je ne suis pas sur un autre périph mais sur le même système
Je vais essayer avec /tmp

EDIT 2 :
même rslt avec /tmp
Ça m’emmerde de devoir changer les droits de preferences (0644).

Comme ça ?

Comme ça ?

/tmp/apt-pref-relais && sudo mv /etc/apt-pref-relais
???

EDIT, compris, je n’avais pas vu le second sudo.
Je teste.

Un rattage :

Bingo :023
T’es trop fort, je vais aller ramasser les feuilles, ça sera plus le domaine de mon neurone :unamused:
:006

Ça serait probablement plus simple de mettre ça dans un script (que tu sauvegarderas par exemple dans /usr/local/bin) qui contienne tes commandes.
Au moins, pas besoin de se rappeler les détails à chaque fois, et tu peux faire un sudo sur le script lui-même.

Et je soutiens la suggestion de MisterFreez, les constantes (ici, le n° de ligne) sont à éviter au maximum car un jour, c’est inévitable, elle va changer car tu éditeras ton fichier preferences… et tu auras complètement oublié d’éditer le script, ce qui foutra le bordel. Par contre contrairement à MisterFreez j’aurais plutôt tendance à fonctionner en prenant un point de repère fixe dans le fichier (est-ce que les blocs apt-listbugs font toujours 4 lignes ?).

[code]# cat > /usr/local/bin/nettoyer-preferences-apt <<EOF
#!/bin/sh

Arrête le script à la moindre erreur, équivalent de commandes toutes enchaînées avec &&

set -e

Récupérer le numéro de ligne à partir duquel faire le découpage

LIGNE="$(grep -n -m 1 -x ‘#### FIN DES PINNINGS PERSONNELS ####’ /etc/apt/preferences | cut -d : -f 1 -s)"

Découper le fichier (on conserve la ligne trouvée, d’où le <= au lieu de < pour awk)

awk “NR<=$LIGNE” /etc/apt/preferences > /etc/apt/preferences.tmp

Faire une sauvegarde au cas où (ça mange jamais de pain)

mv /etc/apt/preferences /etc/apt/preferences~

Remplacer l’ancien preferences

mv /etc/apt/preferences.tmp /etc/apt/preferences
EOF

chmod +x /usr/local/bin/nettoyer-preferences-apt[/code]

Il ne reste plus qu’à rajouter le texte #### FIN DES PINNINGS PERSONNELS #### au bon endroit dans ton fichier /etc/apt/preferences, sachant que tout ce qui se trouve après sera systématiquement nettoyé à chaque utilisation du script.
Ensuite, un simple sudo nettoyer-preferences-apt à chaque utilisation. :wink:

Si je puis me permettre :
paste.isalo.org/78

Sans le EOF final :wink:
paste.isalo.org/79

Pourquoi persister à utiliser grep, cut et awk quand awk fait très bien l’affaire à lui tout seul ?
De plus ma version utilise un fichier temporaire plus fiable et dans /tmp.

Tout simplement parce que je ne sais pas utiliser awk pour trouver le numéro de la ligne marqueur. :wink:
Si tu sais obtenir le même résultat avec une seule commande awk, n’hésite pas. :mrgreen:

Non, dans /tmp c’est beaucoup moins fiable :

[code]$ touch /tmp/foobar
$ ll /tmp/foobar
-rw------- 1 syam syam 0 2011-10-22 19:17 /tmp/foobar
$ su
Mot de passe :

echo “contenu root” > /tmp/foobar

exit

$ ll /tmp/foobar
-rw------- 1 syam syam 13 2011-10-22 19:17 /tmp/foobar
$ echo “contenu pas fiable” > /tmp/foobar
$ cat /tmp/foobar
contenu pas fiable
$ su
Mot de passe :

touch /etc/apt/foobar

ll /etc/apt/foobar

-rw-r–r-- 1 root root 0 2011-10-22 19:18 /etc/apt/foobar

mv /tmp/foobar /etc/apt/foobar

ll /etc/apt/foobar

-rw------- 1 syam syam 19 2011-10-22 19:18 /etc/apt/foobar

exit

$ rm /etc/apt/foobar[/code]
Même si tu fais un rm juste avant d’écrire initialement dans le fichier il y aura toujours une race condition qui fait que le fichier n’est pas fiable, et possiblement exploitable depuis n’importe quel programme qui tourne sur la machine. Dans /etc/apt/ au moins on n’a pas ce problème sachant qu’il est accessible à root uniquement.
Mais la “bonne manière” de faire consiste évidemment à utiliser un nom de fichier temporaire fiable genre mktemp : paste.isalo.org/80 :smiley:

[quote=“syam”]Ça serait probablement plus simple de mettre ça dans un script (que tu sauvegarderas par exemple dans /usr/local/bin) qui contienne tes commandes.
Au moins, pas besoin de se rappeler les détails à chaque fois, et tu peux faire un sudo sur le script lui-même.[/quote]C’était bien envisagé comme ça, au début, je parle de mini-script.
Et même, étant donné que je fais toujours une MAJ après mes sauvegardes hebdomadaires, je vais tout simplement rajouter ces lignes dans mon script de sauvegarde, à la fin, dans ma partie “perso”.

[quote=“syam”]
Et je soutiens la suggestion de MisterFreez, les constantes (ici, le n° de ligne) sont à éviter au maximum car un jour, c’est inévitable, elle va changer car tu éditeras ton fichier preferences… et tu auras complètement oublié d’éditer le script, ce qui foutra le bordel. Par contre contrairement à MisterFreez j’aurais plutôt tendance à fonctionner en prenant un point de repère fixe dans le fichier (est-ce que les blocs apt-listbugs font toujours 4 lignes ?).[/quote]
Le point fixe à trouver est simple avec une première ligne qui commence par “Explanation:”

réponse =
55:Explanation: Pinned by apt-listbugs at Sat Oct 15 00:56:03 +0200 2011
Ensuite, ce que je ne sais pas faire, c’est renvoyer les chiffrers de la réponse dans la commande (sous forme de variable ?)

sudo awk "NR<54" /etc/apt/preferences > /etc/apt/pref-relais && sudo mv /etc/pref-relais /etc/apt/preferences
Comme les “explanations” sont toujours ajoutées à la fin, je ne conserve que jusqu’à la ligne qui précède cette première occurrence de “Explanation:”

EDIT :
il n’accepte pas la commande si ‘pref-relais’ est placé dans /etc/apt :confused:
Demain, je testerai en plaçant dans /home/ricardo

Saleté de moi, je me suis gouré de version dans le pastebin !
Grrrrrrrrr

paste.isalo.org/82

Je ne comprends pas le système du pastbin, quel bloc faut-il copier, celui du bas ou celui du haut.
Pourquoi deux blocs ?

EDIT : erreur ?
cp -f “$ref” “$pref~”

ref ou pref ?

Le bloc du haut sert à présenter et le bloc du bas à copier, mais ils présentent la même chose.

Oui je suis allé vite (j’allais voir le match de rugby chez des amis) c’est pref

Effectivement y’a pas photo, c’est beaucoup plus simple comme ça. :smiley:

Je comprends presque tout le script mais il y a des trous et j’ai besoin d’un cours :

tmpfile=$(mktemp)
je ne connaissais pas cette commande et j’ai lu le man mais ce que je ne comprend pas c’est $ devant, ça équivaut ptet aux `` ?

awk ‘/^Explanation:/{exit}{print $0}’ “$pref” > "$tmpfile"
pour la suite, si tu veux bien me détailler car c’est du Mandarin pour moi.
ce que j’en comprends :
awk cherche Explanation en début de ligne, je suppose qu’il démarre du début du fichier et s’arrête à la 1ère occurrence ?
les // qui entourent Explanation: ???
{exit}{print $0} ???

Le reste, je comprends : tout ce qui précède concerne le fichier $pref et envoie le résultat vers $tmpfile

[quote=“ricardo”]tmpfile=$(mktemp)
je ne connaissais pas cette commande et j’ai lu le man mais ce que je ne comprend pas c’est $ devant, ça équivaut ptet aux `` ?[/quote]
Oui la construction $(…) est équivalente à ...
Perso je trouve la première plus claire à relire, mais bon c’est avant tout une question de goûts. Et accessoirement, on peut imbriquer des $(… $(…) …) sans souci, alors que ce n’est pas faisable avec ...

Pour awk je vais laisser MisterFreez répondre, là je nage autant que toi. :smiley:

Moi ce que je ne vois pas c’est l’endroit où se situe l’extraction du champ à supprimer ou la conservation du seul champ qui doit subsister :
Dans l’ancienne ligne, il y avait :
"NR<54"
Par quoi est-ce remplacé ?

EDIT :
J’ai déjà une réponse partielle trouvée dans un mini-tuto awk :
{print $0} = tous les champs (mais de quoi, la ligne, le paragraphe ???)

les // sont spécifique à awk, apparemment (en dehors de chemins et de la division)