2010-01-21 6 views

Répondre

249

Si vous voulez supprimer des lignes 5 à 10 et 12:

sed -e '5,10d;12d' file 

Cela affichera les résultats à l'écran. Si vous souhaitez enregistrer les résultats dans le même fichier:

sed -i.bak -e '5,10d;12d' file 

Ceci sauvegardera le fichier jusqu'à file.bak et supprimer les lignes données.

+23

Tous les unix n'ont pas gnu sed avec "-i". Ne faites pas l'erreur de retomber dans le fichier "sed cmd file", ce qui effacera votre fichier. – pra

+2

Que faire si je voulais supprimer la 5ème ligne jusqu'à la dernière ligne? – Michelle

+8

@WearetheWorld 'sed -e '5, $ d' file' –

14
$ cat foo 
1 
2 
3 
4 
5 
$ sed -e '2d;4d' foo 
1 
3 
5 
$ 
25

et awk ainsi

awk 'NR!~/^(5|10|25)$/' file 
+0

NB: Cette ligne awk a fonctionné plus sûrement pour moi que la variante sed (entre OS-X et Ubuntu Linux) –

+1

Notez que cela ne supprime rien dans le fichier. Il imprime simplement le fichier sans ces lignes sur stdout. Vous devez également rediriger la sortie vers un fichier temporaire, puis déplacer le fichier temporaire pour remplacer l'original. – mivk

1

Je voudrais proposer une généralisation avec awk.

Lorsque le fichier est fait par des blocs de taille fixe et les lignes à supprimer sont répétées pour chaque bloc, awk peut fonctionner correctement de manière

awk '{nl=((NR-1)%2000)+1; if ((nl<714) || ((nl>1025)&&(nl<1029))) print $0}' 
OriginFile.dat > MyOutputCuttedFile.dat 

Dans cet exemple, la taille de la le bloc est 2000 et je veux imprimer les lignes [1..713] et [1026..1029].

  • NR est la variable utilisée par awk pour stocker le numéro de ligne actuel.
  • % donne le reste (ou le module) de la division de deux nombres entiers;
  • nl=((NR-1)%BLOCKSIZE)+1 Ici, nous écrivons dans la variable nl le numéro de ligne à l'intérieur du bloc actuel. (Voir ci-dessous)
  • || et && sont l'opérateur logique OU et ET.
  • print $0 écrit la gamme complète

Why ((NR-1)%BLOCKSIZE)+1: 
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0. 
    +1 We add again 1 because we want to restore the desired order. 

+-----+------+----------+------------+ 
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 | 
+-----+------+----------+------------+ 
| 1 | 1 | 0  |  1  | 
| 2 | 2 | 1  |  2  | 
| 3 | 0 | 2  |  3  | 
| 4 | 1 | 0  |  1  | 
+-----+------+----------+------------+ 

+2

J'admire la façon dont vous vivez à votre nom induisant la folie. –

13

Vous pouvez supprimer une seule ligne particulière avec son numéro de ligne par fichier sed -i '33d'

Cette va supprimer la ligne sur 33 numéro de ligne et enregistrer le fichier mis à jour.

3

Ceci est très souvent un symptôme d'un anti-modèle. L'outil qui a produit les numéros de ligne peut bien être remplacé par un qui supprime les lignes tout de suite.Par exemple;

grep -nh error logfile | cut -d: -f1 | deletelines logfile 

(où deletelines est l'utilitaire que vous imaginez que vous avez besoin) est le même que

grep -v error logfile 

Cela dit, si vous êtes dans une situation où vous avez vraiment besoin pour effectuer cette tâche, vous peut générer un script sed simple à partir du fichier de numéros de ligne. Humoureusement (mais peut-être légèrement confuse), vous pouvez le faire avec sed.

sed 's%$%d%' linenumbers 

Il accepte un fichier de numéros de ligne, une par ligne, et produit, sur la sortie standard, les mêmes numéros de ligne avec d ajoutés après chaque. Ceci est un script sed valide, que nous pouvons enregistrer dans un fichier, ou (sur certaines plates-formes) conduit à une autre instance sed:

sed 's%$%d%' linenumbers | sed -f - logfile 

Sur certaines plateformes, sed -f ne comprend pas l'argument de l'option - signifie l'entrée standard , donc vous devez rediriger le script vers un fichier temporaire, et le nettoyer lorsque vous avez terminé, ou peut-être remplacer le tiret seul avec /dev/stdin ou /proc/$pid/fd/1 si votre OS (ou shell) a cela.

Comme toujours, vous pouvez ajouter -i avant l'option -f pour que le fichier cible sed soit modifié, au lieu de produire le résultat sur la sortie standard. Sur les plates-formes * BSDish (y compris OSX), vous devez également fournir un argument explicite à -i; un idiome commun est de fournir un argument vide; -i ''. Pouvez-vous donner un exemple plus précis de ce que vous voulez?

+0

Je ne suis pas tout à fait d'accord avec "symptôme d'un antipattern". Les types de fichiers basés sur les annotations (par exemple, XML ou JSON) nécessitent des lignes spécifiques à la fin pour être des fichiers valides. Dans ce cas, c'est souvent l'approche la plus raisonnable pour supprimer ces lignes, mettre dans le fichier ce que vous voulez ajouter, puis rajouter ces lignes, parce que mettre les lignes directement entre elles peut être beaucoup plus difficile et va à l'encontre le désir potentiel d'éviter les outils supplémentaires comme sed autant que vous le pouvez. –

Questions connexes