Comment couper le texte d'un fichier et écrire les modifications dans le même fichier?


1

J'ai un fichier comme:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

Je dois conserver les lignes avec l’horodatage, c’est-à 171023 03014426 1234 XXXX XXXXXXXX- dire à error code: 123partir des autres lignes, c’est-à-dire du début de la ligne jusqu’à la virgule, et écrire les modifications dans le même fichier.

Sortie:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Comment puis je faire ça?


utilisez-vous vim. passer en mode visuel v ou ctrl + v sélectionner l'erreur à, puis appuyer sur d et ajouter à la ligne supérieure à la fin avec A puis p. Ou peut simplement supprimer la nouvelle ligne à la fin de l'horodatage. ou utilisez sed en externe sur ce fichier pour supprimer le nouveau caractère de ligne lors du remplacement sur place
v_sukt

J'ai besoin de la commande de script shell pour faire la même chose
Anony

Réponses:


4

Si j'ai bien compris votre question, vous voulez ceci

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

devenir ceci:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Il y a plusieurs façons de faire cela, alors choisissez la méthode que vous voulez / aimez / préférez.

sed

$ sed 's/\(error code:[[:blank:]][[:digit:]]*\),.*/\1/' input.txt                                     
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Si vous souhaitez apporter des modifications au fichier d'origine input.txt, utilisez sed -iplutôtsed

awk

$ awk -F ',' '/^error code/{$0=$1};1' input.txt                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Cette approche fait en sorte que les virgules soient traitées comme un séparateur de colonnes (dans awk-speak "field"). Nous trouvons donc ici une ligne commençant par error codetext et remplaçant la ligne d'origine par column $1, qui dans votre cas est tout ce qui précède virgule, c'est-à-dire error code: 123.

awkne peut pas éditer dans le texte (la plupart des versions), sed -imais vous pouvez toujours exporter des choses dans un nouveau fichier et remplacer l'ancien fichier par un nouveau comme:

awk -F ',' '/^error code/{$0=$1};1' input.txt > new_data.txt && mv new_data.txt input.txt 

pure bash

#!/usr/bin/env bash

# make temp file for writing stuff
temp=$(mktemp)

# read input file, make necessary changes, write to temp file
while IFS= read -r line;
do
    case $line in
        "error code:"*) printf "%s\n" "${line%%,*}" >> "$temp";;
        *) printf "%s\n" "$line" >> "$temp";;
    esac
done < "$1"
mv  "$temp" "$1"

Essai:

$ # before 
$ cat input.txt                                                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
$ # after
$ ./edit_error_codes.sh input.txt                                                                     
$ cat input.txt
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Au lieu de IFS= read, utiliser IFS=, read -r line extrapeut vous donner la partie avant la virgule gratuitement.
Muru

@muru ouais, j'examinais celui-là aussi; c'est probablement mieux ainsi
Sergiy Kolodyazhnyy

Pourquoi pas un simple cut -d"," -f1?
Ziazis

@Ziazis sûr, peut fonctionner assez bien.
Sergiy Kolodyazhnyy

3

Si les lignes que vous ne souhaitez pas toucher n'ont pas de virgule et que vous souhaitez toujours uniquement supprimer la première virgule et le reste, vous pouvez utiliser une expression très simple.

$ sed 's/,.*//' file
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123
  • s/old/new/remplacer oldparnew
  • .* n'importe quel nombre de caractères

Pour éditer le fichier à la place, utilisez sedl'option in-situ, qui est -i. Si un suffixe pour le fichier de sauvegarde est ajouté après -i, il écrit automatiquement une sauvegarde du fichier d'origine avec cette extension dans le même répertoire, par exemple

sed -i 's/,.*//' file

écrase fileavec le flux modifié, mais

sed -i.orig 's/,.*//' file

écrit le flux modifié dans fileet écrit un nouveau fichier file.origavec le contenu original.


1

Vous pouvez utiliser une simple cutcommande pour faire ce que vous voulez.

cut -d"," -f1 input.txt

Écris-le dans le même fichier.

cut -d"," -f1 input.txt | tee input.txt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.