web-dev-qa-db-fra.com

Recherche et remplacement de la partie numérique d'une chaîne particulière avec une valeur accrue à l'aide de la commande terminal

Le fichier d'entrée est,

test00.dat test07.dat test03.dat
aram22.dat test09.dat aram09.dat
test13.dat

J'ai besoin du fichier de sortie en tant que

test01.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test14.dat

c'est-à-dire que la chaîne numérique associée à test est augmentée d'unité. J'ai besoin d'une ligne de commande de terminal appropriée pour effectuer cette opération.

En particulier, j'ai besoin de connaître le mécanisme de conversion de 'test09.dat' en 'test10.dat' change.

3
tamal

Vous pouvez utiliser le Perl oneliner suivant pour effectuer la transformation:

echo "test00.dat test09.dat aram22.dat" | Perl -pe 's/test\K(\d+)/sprintf "%02d", $1+1/eg'

Résultat:

test01.dat test10.dat aram22.dat

Pour utiliser votre fichier d'entrée:

$ Perl -pe 's/test\K(\d+)/sprintf "%02d", $1+1/eg' your_file
test01.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test14.dat
2
Sylvain Pineau

Une solution quick'n'dirty basée sur Comment trouver et remplacer une chaîne particulière en augmentant sa partie numérique? (suggéré par KasiyA)

echo "test00.dat test07.dat aram22.dat" | Perl -pe 's/(?<=test)(\d+)/$1+1/eg' | sed -e 's/test\([0-9]\)\./test0\1/g'
test01dat test08dat aram22.dat

Notez qu'il y a un bidouillage moche dans ma commande: Perl affiche test1.dat et j'utilise sed pour le corriger sur test01.dat

0
ndemou

Le script ci-dessous suppose que les nombres dans les mots apparaissent consécutivement dans les noms de fichiers (par exemple, file_123.dat, pas file12something345.dat), et les noms des fichiers sont nique.

Ce qu'il fait

  • Il recherche dans le fichier les mots avec des entiers dans le nom.
  • Il convertira ces entiers (consécutifs) int "réels" entiers (valeurs), ce qui supprimera les zéros de tête.
  • Ajouter un à la valeur
  • Comparez ensuite la longueur "originale" de la chaîne numérique avec la valeur modifiée, en ajoutant des zéros non significatifs si la chaîne modifiée est plus courte.

Exemple:

test999.dat test07.dat test03.dat
aram22.dat test09.dat aram09.dat
test0000013.dat

les sorties:

test1000.dat test08.dat test04.dat
aram22.dat test10.dat aram09.dat
test0000014.dat

Le scénario

#!/usr/bin/env python3
import sys

file = open(sys.argv[1]).read()
for w in [w for w in file.split() if w.startswith("test")]:
    try:
        found = "".join([ch for ch in w if ch.isdigit()])
        replace = (len(found), str(int(found)+1))
        file = file.replace(w, w.replace(found, replace[1].zfill(replace[0])))
    except ValueError:
        pass
print(file.strip())

Comment utiliser

  1. Copiez-le dans un fichier vide, enregistrez-le sous le nom add_one.py
  2. Exécutez-le avec le fichier comme argument de la commande:

    python3 /path/to/add_one.py '</path/to/file>`
    
0
Jacob Vlijm

Ici vous êtes une solution bash:

#!/bin/bash

if [ ! -f "$1" ]; then
    echo "File not found!"
    exit
fi

names=$(cat "$1" | sort)

for i in $names; do
    filename=${i%.*}
    extension=${i##*.}
    number=${filename: -2:2}
    name=${filename//[0-9]}
    fnumber=$(printf "%02d\n" $((${number#0}+1)))
    if [[ "$name" == "test" ]]; then
        echo "${name}${fnumber}.${extension}"
    else
        echo "$i"
    fi    
done
0
Helio