Je suis tout nouveau sous UNIX et j'utilise "La ligne de commande Mac OS X" de Kirk McElhearn pour m'enseigner quelques commandes.
J'essaie d'utiliser tr
et grep
pour pouvoir rechercher des chaînes de texte dans un document Word MS-Office standard.
$ tr '\r' '\n' < target-file | grep search-string
Mais tout cela revient:
Illegal byte sequence.
robomechanoid:Position-Paper-Final-Draft robertjralph$ tr '\r' '\n' < Position-Paper-Final-Version.docx | grep DeCSS
tr: Illegal byte sequence
robomechanoid:Position-Paper-Final-Draft robertjralph$
J'ai en fait exécuté la même ligne sur un script que j'ai créé vi
et il effectue correctement la recherche.
text-processing
grep
character-encoding
binary
tr
user74886
la source
la source
Réponses:
grep
est un outil de traitement de texte. Il s'attend à ce que leur entrée soit des fichiers texte . Il semble que la même chose vaut pourtr
macOS (même s'iltr
est censé prendre en charge les fichiers binaires).Les ordinateurs stockent les données sous forme de séquences d' octets . Un texte est une séquence de caractères. Il existe plusieurs façons de coder les caractères sous forme d'octets, appelés codages de caractères . L'encodage de caractères standard de facto dans la plupart du monde, en particulier sur OSX, est UTF-8 , qui est un encodage pour le jeu de caractères Unicode . Il n'y a que 256 octets possibles, mais plus d'un million de caractères Unicode possibles, de sorte que la plupart des caractères sont codés sur plusieurs octets. UTF-8 est un codage de longueur variable: selon le caractère, il peut prendre de un à quatre octets pour coder un caractère. Certaines séquences d'octets ne représentent aucun caractère en UTF-8. Par conséquent, il existe des séquences d'octets qui ne sont pas des fichiers texte UTF-8 valides.
tr
se plaint car il a rencontré une telle séquence d'octets. Il s'attend à voir un fichier texte encodé en UTF-8, mais il voit des données binaires qui ne sont pas des UTF-8 valides.Un document Microsoft Word n'est pas un fichier texte: c'est un document de traitement de texte. Les formats de document de traitement de texte codent non seulement le texte, mais également le formatage, les images incorporées, etc. Le format Word, comme la plupart des formats de traitement de texte, n'est pas un fichier texte.
Vous pouvez demander aux outils de traitement de texte de fonctionner sur des octets en modifiant les paramètres régionaux . Plus précisément, sélectionnez les paramètres régionaux «C», ce qui signifie essentiellement «rien d'extraordinaire». Sur la ligne de commande, vous pouvez choisir les paramètres régionaux avec des variables d'environnement .
Cela n'émettra aucune erreur, mais ne fera rien d'utile non plus car il
target-file
s'agit toujours d'un fichier binaire qui ne contiendra probablement pas la plupart des chaînes de recherche que vous spécifierez.Soit dit en passant, ce
tr '\r' '\n'
n'est pas une commande très utile à moins qu'il ne reste des fichiers texte de Mac OS 9 ou plus.\r
(retour chariot) était le séparateur de nouvelle ligne dans Mac OS avant Mac OS X. Depuis OSX, le séparateur de nouvelle ligne est\n
( saut de ligne, la norme Unix) et les fichiers texte ne contiennent pas de retour chariot. Windows utilise la séquence de deux caractères CR-LF pour représenter les sauts de ligne;tr -d '\r'
convertirait un fichier texte Windows en un fichier texte Unix / Linux / OSX.Alors, comment pouvez-vous rechercher dans un document Word à partir de la ligne de commande? Un
.docx
document Word est en fait une archive zip contenant plusieurs fichiers, les principaux étant en XML .Mac OS X inclut l' utilitaire zipgrep pour rechercher à l'intérieur des fichiers zip.
Le résultat ne sera pas très lisible car les fichiers XML au format docx se composent principalement d'une énorme ligne. Si vous souhaitez rechercher à l'intérieur du corps du texte du document, extrayez le fichier
word/document.xml
de l'archive. Notez qu'en plus du texte du document, ce fichier contient un balisage XML qui représente la structure du document. Vous pouvez masser un peu le balisage XML avecsed
pour le diviser en lignes gérables.la source
xml_pp
en paquetxml-twig-tools
sur Debian Gnu + Linux (je ne connais pas de mac).tr
[...] s'attendre à ce que leur entrée soit des fichiers texte."; tandis que la spécification POSIX indique clairement "L'entrée standard peut être n'importe quel type de fichier." . Veuillez corriger votre réponse.tr
est censée traiter l'entrée binaire (en particulier, elle est censée traiter correctement les octets nuls). Cependant, POSIX ne spécifie pas clairement comment il est censé traiter les entrées qui ne sont pas une séquence de caractères. (Si j'étais un implémenteur, je passerais des séquences d'octets non valides par le biais de non modifiés (ou les supprimerais avec-s
) et soulèverais un défaut avec le comité standard.) Évidemment, le tr de macOS s'en plaint.Je suppose que votre charmap des locales est UTF-8, de sorte que vous aurez des problèmes avec les fichiers binaires. Passez simplement en locale C:
la source
LC_ALL=C ( tr '\r' '\n' < target-file | grep search-string )
. Cependant le docx n'est pas C local. Est utf16 et zippé et complexe et n'importe qui devine. Je dirais que j'utilise un outil qui peut le convertir dans un format différent que vous pouvez traiter, par exemple html ou odt (odt est également compressé, mais bien défini et facile à interpréter).strings
commande donne du texte clair.( export LC_ALL=C; tr '\r' '\n' < target-file | grep search-string; )
devrait fonctionner.strings
a des super pouvoirs: il peut lire des fichiers qui ne sont pas seulement du texte utf-8 ou ascii.()
chose que je pensais que cela fonctionnerait, merci à @ vinc17 pour un correctif.