Étant donné que l'objectif principal de ce fil est de savoir comment faire pour enregistrer en place dans NON GNU awk
, je publie d' abord son modèle qui aidera toute personne dans n'importe quel type d'exigence, ils doivent ajouter / ajouter BEGIN
et END
sectionner dans leur code en gardant leur BLOC principal conformément à leur exigence et il devrait alors effectuer la modification sur place:
REMARQUE: ce qui suit écrira toute sa sortie dans le fichier de sortie, donc si vous souhaitez imprimer quoi que ce soit sur la sortie standard, veuillez uniquement ajouter uneprint...
instruction sans> (out)
suivre.
Modèle générique:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
.....your main block code.....
}
END{
if(rename){
system(rename)
}
}
' *.txt
Solution d'échantillon fournie spécifique:
J'ai trouvé l'approche suivante en awk
elle-même (pour les échantillons ajoutés, voici mon approche pour résoudre ce problème et enregistrer la sortie dans Input_file lui-même)
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print FNR > (out)
}
END{
if(rename){
system(rename)
}
}
' *.txt
REMARQUE: ceci n'est qu'un test pour enregistrer la sortie éditée dans Input_file (s) lui-même, on pourrait utiliser sa section BEGIN, ainsi que sa section END dans leur programme, la section principale devrait être conforme aux exigences de la question spécifique elle-même.
Juste avertissement: Étant donné que cette approche crée un nouveau fichier de sortie temporaire dans le chemin, assurez-vous qu'il y a suffisamment d'espace sur les systèmes, mais au final, cela ne gardera que les fichiers d'entrée principaux, mais pendant les opérations, il a besoin d'espace sur le système / répertoire
Voici un test pour le code ci-dessus.
Exécution du programme avec un exemple: Supposons que les.txt
fichiers d'entréesont lessuivants:
cat << EOF > test1.txt
onetwo three
tets testtest
EOF
cat << EOF > test2.txt
onetwo three
tets testtest
EOF
cat << EOF > test3.txt
onetwo three
tets testtest
EOF
Maintenant, lorsque nous exécutons le code suivant:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print "new_lines_here...." > (out)
}
END{
if(rename){
system("ls -lhtr;" rename)
}
}
' *.txt
REMARQUE: j'ai une placels -lhtr
danssystem
section intentionnellement pour voir quels fichiers de sortie il crée (base temporaire) car plus tard, il les renommera en leur nom réel.
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out2
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out1
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out0
Lorsque nous exécutons un script ls -lhtr
après l' awk
exécution, nous ne pouvons y voir que des .txt
fichiers.
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
Explication: Ajout d'une explication détaillée de la commande ci-dessus ici:
awk -v out_file="out" ' ##Starting awk program from here, creating a variable named out_file whose value SHOULD BE a name of files which are NOT present in our current directory. Basically by this name temporary files will be created which will be later renamed to actual files.
FNR==1{ ##Checking condition if this is very first line of current Input_file then do following.
close(out) ##Using close function of awk here, because we are putting output to temp files and then renaming them so making sure that we shouldn't get too many files opened error by CLOSING it.
out=out_file count++ ##Creating out variable here, whose value is value of variable out_file(defined in awk -v section) then variable count whose value will be keep increment with 1 whenever cursor comes here.
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047" ##Creating a variable named rename, whose work is to execute commands(rename ones) once we are done with processing all the Input_file(s), this will be executed in END section.
} ##Closing BLOCK for FNR==1 condition here.
{ ##Starting main BLOCK from here.
print "new_lines_here...." > (out) ##Doing printing in this example to out file.
} ##Closing main BLOCK here.
END{ ##Starting END block for this specific program here.
if(rename){ ##Checking condition if rename variable is NOT NULL then do following.
system(rename) ##Using system command and placing renme variable inside which will actually execute mv commands to rename files from out01 etc to Input_file etc.
}
} ##Closing END block of this program here.
' *.txt ##Mentioning Input_file(s) with their extensions here.
awk
, (peut-être dans un sous-shell) ou un{...}
groupe inclus, puis écrire les résultats dans le fichier de sortie souhaité (soit pour chaque fichier d'entrée, ou un fichier combiné pour tous les fichiers d'entrée). Ensuite, vous redirigez simplement la sortie du groupe sous-shell ou accolade vers le fichier en cours d'écriture? Le simple fait d'inclure une chaîne de fichiers d'entrée à la suite de laawk
commande traiterait séquentiellement tous les fichiers (ou quelque chose de similaire) ??awk {..} file1 .. fileX
écrire le fichier modifié comme, par exempletemp01
et dans votre prochaine itération lors du traitement du fichier suivant, utilisez unmv -f tmp01 input01
pour écraser le fichier d'entrée avec les données modifiées; ou (2) il suffit d'écrire un nouveau répertoire de./tmp/tmp01 ... ./tmp/tmp0X
pendant l'exécution duawk
script et de suivre avec une boucle sur les fichiers dans le./tmp
répertoire et, par exemplemv -f "$i" "input_${i##*[^0-9]}"
(ou toute autre extension dont vous avez besoin pour remplacer les anciens fichiers d'entrée.awk
l'achèvement complet du code, la deuxième option est presque la même que celle que j'utilise dans ma suggestion. soyez reconnaissant si vous pouviez faire part de vos réflexions sur cette solution, monsieur.