Remplacer le texte d'une cellule CSV en batch

Fermé
adgm1 Messages postés 275 Date d'inscription jeudi 4 octobre 2007 Statut Membre Dernière intervention 11 novembre 2024 - 9 oct. 2023 à 00:30
brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 - 20 oct. 2023 à 11:31

bonjour

je cherche un moyen de remplacer la valeur d'une cellule d'un fichier .csv par une autre. Y a t il une commande batch pour effectuer cela tout en copiant le fichier à analyser vers un nouveau fichier qui contient les nouvelles valeurs.

Par exemple : fichier A.csv (avec les mauvaises valeurs) a des cellules qui contiennent le texte "MATIERE FRANCAIS" , la commande analyse toutes les cellules qui ont cette même valeur puis copie un nouveau fichier B qui doit remplacer les valeurs trouvées par " MAT. FRA." 

Et ainsi de suite pour toutes les autres valeurs indiquées et à modifier vers le nouveau fichier B.csv

Merci

A voir également:

4 réponses

brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 2 599
9 oct. 2023 à 10:31

Bonjour,

Il y a différentes solutions selon que l'occurrence de ces valeurs peut avoir lieu dans plusieurs colonnes ou dans une seule.

Le principe est d'utiliser les paramètres de substitution par SET, démonstration ici à partir d'un fichier texte qui ne contient que MATIERE FRANCAIS; je dois à partir du délimiteur (ici point-virgule), isoler les n premiers caractères et les n derniers, ajouter les points, concaténer les deux:

 

@echo off
setLocal enableDELAYedexpansion
for /f "tokens=* delims=;" %%a in (extract.txt) do (
set str=%%a
set first=!str:~0,3!
set second=!str:~-8,3!
set first=!first!. 
set second=!second!.
echo !first!!second! >> bridge.csv
)

Appliquons à un fichier csv où les valeurs cherchées sont dans la deuxième colonne (variable %%b) et le délimiteur le pipe |.
Même punition, mais nous notons que la chose est laborieuse s'il y a beaucoup de colonnes puisque l'ECHO final doit réordonner touts les colonnes %%a, %%b, %%C (on y observe au passage que les caractères spéciaux, ici le pipe, doivent être échappés par ^).
 

@ECHO OFF
CHCP 65001
SETLOCAL ENABLEDELAYEDEXPANSION 
SET /P nomcsv=entrer le nom du fichier à extraire SANS L'EXTENSION:
(
FOR /f "tokens=1,2,* usebackq delims=|" %%a IN ("%nomcsv%.csv") DO (
 SET "Row2=%%b"
 SET Row21=!Row2:~0,3!
 SET Row22=!Row2:~-8,3!
 SET Row21=!Row21!.
 SET Row22!Row22!.
 SET "Row1=%%a"
 ECHO "%%~a"^|!Row21!!Row22!^|%%c>>"%nomcsv%NEW.csv"
)
)

DEL "%nomcsv%.csv"
REN "%nomcsv%NEW.csv" "%nomcsv%.csv"

GOTO :EOF



Le hic est aussi, que sauf itération complexe, on devra recommencer pour chaque chaîne différente (dont la longueur n'est pas forcément la même) et pour chaque colonne différente.

Une alternative à tester en modifiant à chaque ligne, mais qu'il faudra aussi renouveler pour chaque chaîne sauf à utiliser autant de set line successifs qu'il y en a.

 

@echo off
    setlocal enableextensions enabledelayedexpansion

    (for /f "tokens=*" %%f in (a.csv) do if not "%%f"=="" (
            set "line=%%f"
            set "line=!line:MATIERE FRANCAIS=MAT. FRA!"
            echo(!line!
    )) > b.csv

    endlocal
DEL a.csv
REN b.csv a.csv
1
adgm1 Messages postés 275 Date d'inscription jeudi 4 octobre 2007 Statut Membre Dernière intervention 11 novembre 2024 10
9 oct. 2023 à 13:02

ok merci. Dans mon cas c'est uniquement dans une colonne donnée que les valeurs doivent etre changées. je ne suis pas sur de comprendre dans ton premier exemple de script pourquoi il y a set row 2 puis set row 1. Dans l'idée je n'ai que la colonne 3 ou il faut changer des valeurs par une valeur abrégée et la colonne 4 qui est vide aurait besoin d'une valeur identique à appliquer à toutes les lignes.

0
brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 2 599
9 oct. 2023 à 14:40

Ligne 7 (utiliser le délimiteur approprié), Row2 représente ce qu'il y a après le premier délimiteur, donc la deuxième colonne qui contient MATIERE FRANCAIS, je sépare les 2 mots plus les points par les valeurs successives de Row21 et Row22.

Ligne 13, je reconstitue la ligne qui dans mon cas de figure ne comporte que 3 colonnes %%a %%b et %%c et où la valeur de %%b a été reconstituée en recollant les morceaux modifiés Row21 et Row22.

Dans ton cas, tu dois utiliser %%c ligne 7 et la ligne 13 devient (avec un délimiteur pipe):
 

ECHO "%%~a"^|%%b^|!Row21!!Row22!^|%%d>>"%nomcsv%NEW.csv"

Je n'ai pas compris ce que tu veux mettre en %%d (colonne 4 vide)

0
adgm1 Messages postés 275 Date d'inscription jeudi 4 octobre 2007 Statut Membre Dernière intervention 11 novembre 2024 10
9 oct. 2023 à 19:28

ok je vais tester. pour la colonne 4 qui est vide à priori j'aimerais imposer un mot dans chacune des cases de la colonne. En s'arrêtant bien sur à la dernière ligne qui contient du texte. Donc si j'ai 15 lignes de données, il faudrait que la colonne 4, peut importe ce qu'elle comporte (vide ou autre valeur) puisse obtenir une unique valeur textuelle (ex: maison) de D1 à D15 ou plutot D2 à D16 puisque la premiere ligne est un titre.

0
brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 2 599
9 oct. 2023 à 21:46

Tu as bien fait de me remonter les bretelles, j'ai une pagaille de fichiers xls mais je n'avais plus qu'une base de données csv longue comme un jour sans pain; j'ai créé un fichier test et corrigé les bugs.

La ligne CHCP ne sert que s'il doit y avoir un ECHO de caractères spéciaux (accents...)

 

@ECHO OFF
CHCP 65001>NUL
SETLOCAL ENABLEDELAYEDEXPANSION 
SET /P nomcsv=entrer le nom du fichier à extraire SANS L'EXTENSION:

FOR %%g IN (%nomcsv%*.csv) DO (
SET "line="
SET /P "line="<"%%~g"
ECHO(!line!>>"%nomcsv%NEW.csv" 
)

FOR /F "skip=1 tokens=1-4 usebackq delims=|" %%a IN ("%nomcsv%.csv") DO (
 SET "Row1=%%a"
 SET "Row2=%%b"
 SET "Row3=%%c"
 SET "Row4=%%d"
 SET Row31=!Row3:~0,3!
 SET Row32=!Row3:~-8,3!
 SET "Row4=maison"
 ECHO !Row1!^|!Row2!^|!Row31!. !Row32!.^|!Row4!>>"%nomcsv%NEW.csv"
)
)

DEL "%nomcsv%.csv"
REN "%nomcsv%NEW.csv" "%nomcsv%.csv"

GOTO :EOF
0
adgm1 Messages postés 275 Date d'inscription jeudi 4 octobre 2007 Statut Membre Dernière intervention 11 novembre 2024 10
20 oct. 2023 à 01:57

Super travail Brucine, merci beaucoup.

J'ai utilisé ça pour modifier le nom de certaines cellules et ça fonctionne bien :

    (for /f "tokens=*" %%f in (a.csv) do if not "%%f"=="" (
            set "line=%%f"
            set "line=!line:MATIERE FRANCAIS=MAT. FRA!"
            set "line=!line:MATIERE MATHEMATIQUES=MATH!"
            ...
            echo(!line!
    )) > b.csv

Par contre je me perd un peu en ce qui concerne le forçage du mot "maison" dans la colonne 4.

0
brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 2 599
20 oct. 2023 à 10:00

Pagnol aurait dit que cela dépend de la grandeur des tiers (de la structure de ton fichier CSV, mets en ligne un extrait anonymisé en cas de besoin).

Ta condition sur ligne vide ne sert à rien et met le souk: même s'il y en a une, elle ne sortira pas dans le fichier CSV.

La question, si j'ose, est de savoir où est la maison; si elle doit figurer dans la dernière colonne, il suffit de la rajouter, et de ne pas oublier le délimiteur adapté (dans mon cas de figure | mais si dans le fichier CSV c'est un espace on va avoir des soucis du fait que certaines cellules contiennent des espaces):
 

setlocal enabledelayedexpansion
for /f "tokens=* delims=|" %%f in (string.csv) do (
           set "line=%%f" 
           set "line=!line:MATIERE FRANCAIS=MAT.FRA!"
           set "line=!line:MATIERE MATHEMATIQUES=MATH!"
	   echo !line!maison >> b.csv          
)

Si elle doit être construite dans une colonne intermédiaire (la quatrième s'il y en a 6) on est bien obligé, même si on utilise dans un premier temps ta syntaxe, d'utiliser une boucle supplémentaire pour spécifier la colonne à modifier et conserver les suivantes (en <5>, les lignes 12 et 16 font que la quatrième colonne est %%d et je recolle les colonnes que j'ai zappées ensuite).

0
brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024 2 599 > brucine Messages postés 17799 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 21 novembre 2024
20 oct. 2023 à 11:31

Une façon plus simple de tricher si les cellules vides dans le fichier CSV existent déjà et comportent un espace entre délimiteurs, ici la quatrième:

3989394|2021-10-07|MATIERE FRANCAIS| |
 

set "line=!line: =maison!"

et cette fois-ci indépendamment de la colonne

0