J'ai un fichier results.csv qui contient des noms dans la mise en page suivante:
record_seperator name2 bla bluh
et un sample.txt, qui est structuré comme suit
record_seperator name1 foo bar
4 Réponses :
En voici une. Comme il n'y avait pas de sortie attendue, il ne produit que des enregistrements bruts :
$ cat name1.txt record_seperator name1 foo bar
Une seule correspondance:
$ awk ' NR==FNR { # process first file a[$1]=RS $0 # hash the whole record with first field (name) as key next # process next record in the first file } # after this line second file processing $1 in a { # if first field value (name) is found in hash a f=$1 ".txt" # generate filename print a[$1] > f # output the whole record close(f) # preserving fds }' RS="record_seperator\n" sample RS="\n" FS="," results # file order and related vars
Testé sur gawk et mawk, agit bizarrement sur original-awk.
Merci pour la réponse rapide. Je dois admettre que je ne le comprends pas entièrement. J'ai ajouté la sortie attendue dans mon message d'origine.
le résultat doit contenir la ligne RS "record_seperator"
Merci beaucoup pour vos réponses! Désolé de rentrer si tard. J'ai eu la grippe et puis une tonne de travail s'est accumulée.
quelque chose comme ça, ( non testé )
$ awk -F, 'NR==FNR {a[$1]; next} # fill array with names from first file $1 in a {print rt, $0 > ($1".txt")} # print the record from second file {rt = RT}' results.csv RS="define_it_here" sample.txt
puisque votre séparateur d'enregistrements est avant les enregistrements, vous devez le retarder de un.
Utilisez l'itérateur de construction en ligne / enregistrement au lieu de le contourner.
(En suivant l'exemple de @ Tiw, j'ai également changé name5 en name2 dans votre fichier de résultats afin d'obtenir le résultat attendu)
$ cat name1.txt record_seperator name1 foo bar $ cat name2.txt record_seperator name2 bla bluh
Exécutez avec gawk pour RS multi-caractères: p >
$ gawk -f a.awk FS="," results.csv FS="\n" RS="record_seperator\n" sample.txt
Résultats de la vérification:
$ cat a.awk # collect the result names into an array NR == FNR {a[$1]; next} # skip the first (empty) sample record caused by initial record separator FNR == 1 { next } # If found, output sample record into the appropriate file $1 in a { f = ($1 ".txt") printf "record_seperator\n%s", $0 > f }
Vous codez les erreurs:
record_seperator name1 foo bar record_seperator name2 bla bluh
Aussi l'exemple que vous avez montré:
#!/bin/bash awk 'BEGIN{ while ( (getline line< "results.csv") > 0 ) { # Avoid infinite loop when read erorr encountered. split(line,name,","); nameArr[name[1]]; # Actually no need do anything, just refer once to establish the key (name[1]). } RS="record_seperator"; FS="\n"; } $2 in nameArr { print RS $0; #You can add `> $2 ".txt"` later yourself. }' sample.txt
Changement de name5
en nom2 , et avec votre propre code mis à jour:
name1, 2(random number) name5, 3 ## <-- name5 here, not name2 !
Sortie:
#!/bin/bash awk 'BEGIN{ while (getline < "results.csv") { split($0,name,","); nameArr[k]=name[1]; ## <-- k not exists, you are rewriting nameArr[""] again and again. } { RS="record_seperator" FS="\n" for (key in nameArr) ## <-- only one key "" exists, it's never gonna equal to $2 { print nameArr[key] print $2 if ($2==nameArr[key]) NR > 1 { #extract file by Record separator and name from line2 print RS $0 > $2 ".txt" } } } }' sample.txt