J'ai une sortie qui est un fichier texte comme celui-ci ( C: \ test.txt
)
@echo off SET _c= FOR /F "tokens=4 delims= " %%G IN (C:\test.txt) DO ( IF DEFINED _c <nul set /p z=", " <nul set /p z=%%G SET _c=1 )
Inutile de dire que c'était un gâchis. Cependant, j'aimerais avoir la valeur de la colonne "non utilisée" qui est 111640.
Ma machine est Windows, j'ai essayé le code suivant mais cela ne m'a rien donné:
database_name |database_size |unallocated space --------------------------------------------------------------------------------------------------------------------------------|------------------|------------------ web | 11120.00 MB |11157.80 MB (1 sËââ³âêâÃâµâ½) reserved |data |index_size |unused ------------------|------------------|------------------|------------------ 111360 KB |11560 KB |11160 KB |111640 KB (1 sËââ³âêâÃâµâ½)
Quelqu'un peut me dire comment obtenir cette valeur?
8 Réponses :
Étant donné que votre question est balisée awk , comment à propos de
awk -F "|" "$NF ~ /unused/{p=1} p && /[0-9]/ { print $NF; p = 0 }" messyfile.txt
J'espère que les guillemets sont appropriés pour Windows; sur U * x, j'utiliserais des guillemets simples partout.
-F
définit le séparateur de champ, NF
est le nombre de champs; donc $ NF
examine le dernier champ de chaque ligne. Si nous voyons non utilisé
dans le dernier champ, commencez à chercher un nombre. Lorsque nous voyons une ligne qui contient au moins un nombre, imprimez le dernier champ de cette ligne.
Si c'est assez proche de ce que vous voulez, j'espère que vous pouvez trouver comment le modifier, par exemple. pour supprimer le suffixe KB
(indice: sub ()
ou split()
).
@Tiw Merci pour la modification. Maudit soit le clavier mobile.
Bien sûr, j'en ai repéré un mais pas l'autre.
J'apprécie vraiment votre aide. J'utiliserais aussi ceci sur ma machine Linux.
Pourriez-vous s'il vous plaît essayer de suivre (je n'ai pas testé ceci sur l'environnement Windows).
code.awk !flag{ for(i=1;i<=NF;i++){ if($i~/unused/){ field=i flag=1 } } } flag && !/^-/{ print $field,$(field+1) flag="" exit }'
Vous devez changer les guillemets simples en "
au cas où vous l'êtes sous Windows.
Explication: Ce code recherche le numéro de champ où la chaîne non utilisée
est trouvée et puis quelle que soit la ligne suivante (sans -
), il affichera ce champ spécifique et son suivant (qui contient des informations de kb
etc.). Je ne suis pas le numéro de champ de codage en dur ici pour Chaîne non utilisée
.
Selon le commentaire de @ MarkSetchell, nous pourrions essayer de créer un fichier code.awk
et l'exécuter comme awk -f code .awk Input_file
où Input_file est l'exemple de fichier.
awk '!flag{for(i=1;i<=NF;i++){if($i~/unused/){field=i;flag=1}}} flag && !/^-/{print $field,$(field+1);flag="";exit}' Input_file
PS: Attention, je n'ai pas testé cela sur l'environnement Windows
@Tiw, comme tripleee monsieur, j'ai ajouté le changement '
à "
dans le cas de Windows. Puisque je n'ai pas d'environnement Windows avec moi, j'ai ajouté un avertissement juste dans mon solution maintenant + Je vérifie le terminal en ligne si je l'obtiens pour vérifier si cela fonctionne (Windows One).
Vous pouvez contourner la plupart des insuffisances de Windows en plaçant votre script awk
dans un fichier séparé et en l'exécutant avec awk -f thatFile
... :-)
@MarkSetchell, cool, permettez-moi de l'essayer aussi et MERCI une TONNE de me l'avoir fait savoir, ajoutera cela dans mon message maintenant.
@MarkSetchell, a ajouté le code de type .awk
maintenant, mais je ne l'ai pas testé, merci de l'avoir fait savoir. Je vais essayer de le tester. N'hésitez pas à modifier ou à me le faire savoir au cas où vous trouveriez quelque chose qui ne fonctionne pas.
Ne me forcez pas à le faire - je ne veux pas exécuter Windows! :-) La seule façon d'exécuter Windows est dans VirtualBox, alors toute cette méchanceté est dans un seul fichier VMDK que je peux facilement supprimer en une seule fois!
Essayez cette version batch / cmd:
@echo off for /f "usebackq" %%i in (`for /f "tokens=4 delims=|" %%j in ^(C:\test.txt^) do @echo %%j`) do ( (echo %%i | findstr /R "[0-9][0-9]*" ) && set "thenum=%%i" && goto :outloop ) :outloop ::echo %thenum% ::pause
La valeur est également enregistrée dans la variable thenum
et peut être utilisée plus tard.
p >
Ce script de fichier .bat peut vous donner ce que vous voulez.
powershell -NoLogo -NoProfile -Command ^ "Select-String -Path '.\test.txt' -Pattern '^\d+ .*\|\d+ .*\|\d+ .*\|(\d+).*$' |" ^ "ForEach-Object { $_.Matches.Groups[1].Value }"
Vous pouvez raccourcir avec un groupe non capturant (? :)
et un quantificateur {3}
=> -Pattern '^ (?: \ D +. * \ | ) {3} (\ d +). * $ '| "
@LotPings - Oui, j'y ai pensé. Mais ce n'est pas beaucoup plus court et, pour moi, ce qu'il recherche est moins évident.
Cela vous donne accès à toutes les données de votre fichier d'entrée sous le nom de cette valeur:
$ cat tst.awk BEGIN { FS = "[[:space:]]*[|][[:space:]]*" } { gsub(/^[[:space:]]+|[[:space:]]+$/,"") } prev1 ~ /^[-|]+$/ { split(prev2,tags) for (i=1; i<=NF; i++) { tag = tags[i] val = $i tag2val[tag] = val } } { prev2 = prev1; prev1 = $0 } END { sep = "" for (tag in tag2val) { printf "%s%s", sep, tag sep = "," } print "" sep = "" for (tag in tag2val) { printf "%s%s", sep, tag2val[tag] sep = "," } print "" } $ awk -f tst.awk file reserved,unallocated space,database_name,data,database_size,index_size,unused 111360 KB,11157.80 MB,web,11560 KB,11120.00 MB,11160 KB,111640 KB
Si vous souhaitez une sortie CSV, ajustez simplement la section END:
$ cat tst.awk BEGIN { FS = "[[:space:]]*[|][[:space:]]*" } { gsub(/^[[:space:]]+|[[:space:]]+$/,"") } prev1 ~ /^[-|]+$/ { split(prev2,tags) for (i=1; i<=NF; i++) { tag = tags[i] val = $i tag2val[tag] = val } } { prev2 = prev1; prev1 = $0 } END { for (tag in tag2val) { val = tag2val[tag] printf "%s = <%s>\n", tag, val } print "---" print tag2val["unused"] } $ awk -f tst.awk file reserved = <111360 KB> unallocated space = <11157.80 MB> database_name = <web> data = <11560 KB> database_size = <11120.00 MB> index_size = <11160 KB> unused = <111640 KB> --- 111640 KB
Apprécier ton aide. Script incroyable.
En regardant le contenu du fichier fourni, vous n'avez pas vraiment besoin d'un masque de recherche complexe:
@Echo Off Set "UnUsed=" For /F "Tokens=4 Delims=|" %%A In ('Find " KB"^<"C:\test.txt" 2^>Nul' ) Do For %%B In (%%A) Do If Not Defined UnUsed Set "UnUsed=%%B" If Defined UnUsed (Echo=%UnUsed% & Pause)
Comme dans un fichier batch, les délimiteurs consécutifs sont comptés comme celui que j'utiliserais
Sur la ligne cmd
@Echo off for /f "tokens=7 delims=| " %%A in ('findstr "KB" C:\test.txt') do set "unused_KB=%%A"
Dans un fichier batch
for /f "tokens=7 delims=| " %A in ('findstr "KB" C:\test.txt') do @set "unused_KB=%A"
Un autre (plus simple), juste pour la collection!
@echo off for /F "tokens=7 delims=| " %%a in (test.txt) do set "col=%%a" echo %col%
Le jeton désiré est deux (2) lignes en dessous de celui de recherche. La ligne du jeton souhaité a deux jetons pour chacun d'eux dans la ligne de recherche. Pour cette raison, le décalage du jeton est de 3 (au lieu de 0).
Une explication détaillée de cette méthode est donnée à ce site
MODIFIER : Nouvelle méthode ajoutée
Cette méthode simple et standard fonctionne également car la valeur souhaitée est le seul septième jeton du fichier!
@echo off setlocal for /F "tokens=3" %%a in ('"setx /F test.txt dummyVar /R 2,3 unused /D ^|"') do set "col=%%a" & goto continue :continue set "col=%col:~0,-1%" echo %col%
Il devrait y avoir un moyen avec
FINDSTR
et les paramètres/ r
et une expression régulière quelque chose comme[0-9] * KB $
Pouvez-vous utiliser
gawk
? Ce fichier est-il également terminé par des retours chariot?