J'ai un fichier contenant les lignes suivantes:
<parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter>
<parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter>
<parameter name="RemoteHost" access="readWrite"></parameter>
<parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="PortMappingProtocol" access="readWrite"></parameter>
<parameter name="InternalClient" access="readWrite"></parameter>
<parameter name="PortMappingDescription" access="readWrite"></parameter>
Je veux exécuter la commande sur ce fichier pour extraire uniquement les noms de paramètre tels qu'ils apparaissent dans la sortie suivante:
$sedcommand file.txt
PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription
Quelle pourrait être cette commande?
Vous voulez awk
.
Ce serait un hack rapide et sale:
awk -F "\"" '{print $2}' /tmp/file.txt
PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription
grep est né pour extraire des choses:
grep -Po 'name="\K[^"]*'
tester avec vos données:
kent$ echo '<parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter>
<parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter>
<parameter name="RemoteHost" access="readWrite"></parameter>
<parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
<parameter name="PortMappingProtocol" access="readWrite"></parameter>
<parameter name="InternalClient" access="readWrite"></parameter>
<parameter name="PortMappingDescription" access="readWrite"></parameter>
'|grep -Po 'name="\K[^"]*'
PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription
sed 's/[^"]*"\([^"]*\).*/\1/'
fait le travail.
Vous ne devez pas analyser XML à l'aide d'outils tels que sed ou awk. C'est sujet aux erreurs.
Si l'entrée change, et avant le paramètre name, vous obtiendrez un caractère de nouvelle ligne au lieu d'un espace, il échouera un jour et produira des résultats inattendus.
Si vous êtes vraiment sûr que votre entrée sera toujours formatée de cette façon, vous pouvez utiliser cut
. C'est plus rapide que sed
et awk
:
cut -d'"' -f2 < input.txt
Il sera préférable de l’analyser d’abord et d’extraire uniquement l’attribut name:
xpath -q -e //@name input.txt | cut -d'"' -f2
Pour en savoir plus sur xpath, consultez ce tutoriel: http://www.w3schools.com/xpath/
Expliquant comment utiliser cut
:
cat yourxmlfile | cut -d'"' -f2
Il "coupera" toutes les lignes du fichier en fonction de "d élimiter, et prendra le 2 nd f ield, qui est ce que tu voulais.