Quel est le moyen le plus simple de supprimer tous les retours chariot \r
d'un fichier sous Unix?
Je vais supposer que vous voulez parler des retours de voiture (CR, "\r"
, 0x0d
) aux extrémités des lignes plutôt qu’à l’aveuglette dans un fichier (vous pouvez les avoir au milieu de chaînes pour tout ce que je sais) . Utilisation de ce fichier de test avec un CR à la fin de la première ligne uniquement:
$ cat infile
hello
goodbye
$ cat infile | od -c
0000000 h e l l o \r \n g o o d b y e \n
0000017
dos2unix
est le chemin à suivre s'il est installé sur votre système:
$ cat infile | dos2unix -U | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Si, pour une raison quelconque, dos2unix
n'est pas disponible, sed
le fera:
$ cat infile | sed 's/\r$//' | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Si pour une raison quelconque, sed
n'est pas disponible, alors ed
le fera, de manière compliquée:
$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Si vous n'avez aucun de ces outils installés sur votre machine, vous avez de plus gros problèmes que d'essayer de convertir des fichiers :-)
tr -d '\r' < infile > outfile
Voir tr (1)
Vieille école:
tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
Il existe un utilitaire appelé dos2unix qui existe sur de nombreux systèmes et peut être facilement installé sur la plupart.
Le plus simple sur Linux est, à mon humble avis,
sed -i 's/\r//g' <filename>
Les citations strong autour de l'opérateur de substitution 's/\r//'
sont essentiel. Sans eux, le shell interprétera \r
comme un échappement + r et le réduira en un simple r
et supprimera tous les minuscules r
. C'est pourquoi la réponse donnée ci-dessus en 2009 par Rob ne fonctionne pas.
Et ajouter le modificateur /g
garantit que même plusieurs \r
seront supprimés, et pas seulement le premier.
sed -i s/\r// <filename>
ou quelque chose comme ça; voir man sed
ou la richesse des informations disponibles sur le Web concernant l’utilisation de sed
.
Une chose à souligner est la signification précise de "retour de chariot" dans ce qui précède; Si vous voulez vraiment parler du caractère de contrôle unique "retour de chariot", le modèle ci-dessus est correct. Si vous vouliez parler plus généralement de CRLF (retour à la ligne et saut de ligne, méthode d’implémentation des sauts de ligne sous Windows), vous souhaiterez probablement remplacer \r\n
. Les sauts de ligne nus (newline) sous Linux/Unix sont \n
.
Si vous êtes un utilisateur de Vi, vous pouvez ouvrir le fichier et supprimer le retour chariot avec:
:%s/\r//g
ou avec
:1,$ s/^M//
Notez que vous devez taper ^ M en appuyant sur ctrl-v puis sur ctrl-m.
Une fois de plus une solution ... Parce qu'il y en a toujours une de plus:
Perl -i -pe 's/\r//' filename
C'est agréable parce qu'il est en place et qu'il fonctionne dans toutes les saveurs d'Unix/Linux avec lesquelles j'ai travaillé.
Quelqu'un d'autre recommande dos2unix
et je le recommande fortement. Je fournis juste plus de détails.
Si installé, passez à l'étape suivante. Si ce n'est déjà fait, je recommanderais de l'installer via yum
comme:
yum install dos2unix
Ensuite, vous pouvez l'utiliser comme:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Voici la chose,
%0d
est le caractère de retour chariot. Pour le rendre compatible avec Unix. Nous devons utiliser la commande ci-dessous.
dos2unix fileName.extension fileName.extension
Pour UNIX ... j'ai remarqué que dos2unix avait supprimé les en-têtes Unicode de mon fichier UTF-8. Sous git bash (Windows), le script suivant semble bien fonctionner. Il utilise sed. Notez qu'il supprime uniquement les retours à la fin des lignes et conserve les en-têtes Unicode.
#!/bin/bash
inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
Si vous utilisez un environnement X et que vous avez un éditeur approprié (code Visual Studio), je vous recommande de suivre la recommandation suivante:
Code Visual Studio: Comment afficher les fins de ligne
Allez dans le coin en bas à droite de votre écran. Le code Visual Studio vous montrera à la fois l’encodage du fichier et la convention de fin de ligne suivie du fichier. Un simple clic suffit pour inverser la liste.
Utilisez simplement du code visuel pour remplacer notepad ++ dans un environnement linux et vous êtes prêt à partir.
essayez ceci pour convertir le fichier dos en fichier unix:
fichier fromdos
Si vous utilisez un système d'exploitation (comme OS X) qui ne dispose pas de la commande dos2unix
mais dispose d'un interpréteur Python (version 2.5+), cette commande est équivalente à la commande dos2unix
:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
Cela gère les deux fichiers nommés sur la ligne de commande, ainsi que les tubes et les redirections, tout comme dos2unix
. Si vous ajoutez cette ligne à votre fichier ~/.bashrc (ou à un fichier de profil équivalent pour d'autres shells):
alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""
... la prochaine fois que vous vous connecterez (ou exécuterez source ~/.bashrc
dans la session en cours), vous pourrez utiliser le nom dos2unix
sur la ligne de commande de la même manière que dans les autres exemples.
J'ai utilisé python pour cela, voici mon code;
end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
with open(end2, "w") as fixed:
for line in inf:
line = line.replace("\n", "")
line = line.replace("\r", "")
fixed.write(line)
Bien que ce soit un article plus ancien, je suis récemment tombé sur le même problème. Comme j'avais tous les fichiers à renommer dans/tmp/blah_dir /, chaque fichier de ce répertoire ayant le caractère "/ r" (indiquant "?" En fin de fichier), je ne pouvais donc que le penser.
Je voulais sauvegarder le fichier final avec le même nom (sans aucun caractère). Avec sed, le problème était le nom du fichier de sortie auquel il fallait mentionner autre chose (que je ne voulais pas).
J'ai essayé d'autres options, comme suggéré ici (non considéré dos2unix en raison de certaines limitations), mais cela n'a pas fonctionné.
J'ai essayé avec "awk" finalement qui a fonctionné où j'ai utilisé "\ r" comme délimiteur et pris la première partie :
le truc c'est:
echo ${filename}|awk -F"\r" '{print $1}'
L'extrait de script ci-dessous que j'ai utilisé (où j'avais tous les fichiers qui avaient "\ r" comme caractère final dans le chemin/tmp/blah_dir /) pour résoudre mon problème:
cd /tmp/blah_dir/
for i in `ls`
do
mv $i $(echo $i | awk -F"\r" '{print $1}')
done
Note: Cet exemple n'est pas très exact bien que proche de ce que j'ai travaillé (Mentionner ici juste pour donner une meilleure idée de ce que j'ai fait)
\r
_ sur n’importe quel système UNIX:La plupart des solutions existantes dans cette question sont spécifiques à GNU et ne fonctionneraient pas sous OS X ou BSD; Les solutions ci-dessous devraient fonctionner sur de nombreux autres systèmes UNIX et dans tous les Shell, de tcsh
à sh
, tout en fonctionnant toujours même sous GNU/Linux.
Testé sous OS X, OpenBSD et NetBSD sous tcsh
et sous Debian GNU/Linux sous bash
.
sed
:Dans tcsh
sous OS X, l’extrait suivant sed
peut être utilisé avec printf
, car ni sed
ni echo
ne manipule _\r
_ de manière particulière, comme le GNU:
_sed `printf 's/\r$//g'` input > output
_
tr
:Une autre option est tr
:
_tr -d '\r' < input > output
_
sed
et tr
:Il semblerait que tr
préserve l’absence de nouvelle ligne finale du fichier d’entrée, alors que sed
sous OS X et NetBSD (mais pas sous OpenBSD ou GNU/Linux) insère une nouvelle ligne finale à la toute fin du fichier, même si la il manque tout _\r
_ ou _\n
_ final à la toute fin du fichier.
Voici quelques exemples de tests qui pourraient être utilisés pour vérifier que cela fonctionne sur votre système, en utilisant printf
et hexdump -C
; alternativement, od -c
peut également être utilisé si votre système manque de hexdump
:
_% printf 'a\r\nb\r\nc' | hexdump -C
00000000 61 0d 0a 62 0d 0a 63 |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000 61 0a 62 0a 63 0a |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000 61 0a 62 0a 63 |a.b.c|
00000005
%
_