2011-04-19 4 views
13

Ive vu beaucoup de variations, très confus sur la façon de résoudre ces 3 problèmes.Supprimer les lignes du fichier avec SED ou AWK

  1. suppression de toutes les lignes sauf la première à partir d'un fichier
  2. suppression d'une ligne de fichier avec un numéro de ligne
  3. suppression de lignes à partir d'un fichier avec une gamme de numéros de ligne

Répondre

24

Utilisation sed:

Supprimer 1ère ligne:

sed '1d' file-name 

Supprimer 10e ligne:

sed '10d' file-name 

ligne Supprimer n ° 5 à 10

sed '5,10d' file-name 

Toutes les commandes ci-dessus sed écriront sortie sur la sortie standard que vous pouvez rediriger vers un autre fichier si vous voulez ou utilisez -i drapeau sed pour inline éditer le fichier.

+1

Pour supprimer * toutes les lignes sauf la première *, 'sed '2, $ d' filename', ou' sed '1! d' filen ame', ou 'sed -n '1p' nom de fichier'. – Beta

+0

@Beta, les deux premiers sont exactement corrects, mais le troisième n'imprimera que la première ligne. – dubiousjim

+1

@dubiousjim: «Imprimer la première ligne seulement» est identique à «supprimer toutes les lignes sauf la première», c'est pourquoi 'sed -n '1p'' est également correct. – anubhava

7

Avec awk:

# delete line 1 
awk 'NR == 1 {next} {print}' file 

# delete line number stored in shell variable $n 
awk -v n=$n 'NR == n {next} {print}' file 

# delete between lines $a and $b inclusive 
awk -v m=$a -v n=$b 'm <= NR && NR <= n {next} {print}' file 

Pour enregistrer quelques caractères, {print} peut être remplacé juste avec 1

Pour écraser le fichier d'origine, vous devez faire quelque chose comme ça

awk '...' file > tmpfile && mv tmpfile file 
+0

Comment puis-je obtenir la sortie de awk pour ne pas apparaître? – bluetickk

+0

ok cela fonctionne, mais les lignes sont en train d'imprimer et de ne pas enregistrer dans le fichier? – bluetickk

+0

@bluetickk, mis à jour ma réponse –

0

vous pouvez simplement utiliser bash si votre système l'a. L'idée de base est de définir un nombre et d'incrémenter ce nombre pendant l'itération du fichier.

1) la suppression de toutes les lignes sauf la première à partir d'un fichier

read -r line < file; echo "$line" > temp && mv temp file 

2) suppression d'une ligne de fichier avec un numéro de ligne

declare -i count=0 
while read -r line 
do 
    ((count++)) 
    case "$count" in 
    10) continue;; 
    *) echo "$line";; 
    esac 
done <file> temp && mv temp file 

3) suppression de lignes à partir d'un fichier avec une gamme de numéros de ligne, par exemple de 10 à 20

declare -i count=0 
while read -r line 
do 
    ((count++)) 
    if (($c < 10 && $c > 20));then 
    echo "$line";; 
    fi 
done <file> temp && mv temp file 
+0

De la façon dont vous l'utilisez, 'read -r' supprimera toujours les espaces de début et de fin. Vous devez faire 'IFS = read -r line'.Notez également que cette méthode est plus rapide pour les petits fichiers car elle évite une fourche, mais plus lente pour les fichiers volumineux car 'read' est intrinsèquement inefficace et lit généralement un octet à la fois ou fait un appel read et lseek par invocation et le traitement des chaînes dans bash a tendance à être inefficace (moins dans les autres shells). – jilles

+0

@jilles, merci d'avoir oublié IFS = sur ces cas. Et oui, je sais que 'read' est inefficace sur les gros fichiers avec' bash'. Si les fichiers OP sont de grandes tailles et que les performances posent problème, utilisez un outil plus performant. –

Questions connexes