web-dev-qa-db-fra.com

Supprimer le retour chariot dans Unix

Quel est le moyen le plus simple de supprimer tous les retours chariot \r d'un fichier sous Unix?

188
Aldur

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 :-)

241
paxdiablo
tr -d '\r' < infile > outfile

Voir tr (1)

209
Henrik Gustafsson

Vieille école:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
34
plinth

Il existe un utilitaire appelé dos2unix qui existe sur de nombreux systèmes et peut être facilement installé sur la plupart.

27
Emil H

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.

18
wfjm

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.

7
Rob

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.

6
Alex Giotis

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é.

6
Allan Cano

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
3
James Oravec

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

2
Sireesh Yarlagadda

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"
1
LexieHankins

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.

1
99Sono

essayez ceci pour convertir le fichier dos en fichier unix:

fichier fromdos

1
hawston

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.

1
Chris Johnson

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)
0
Raphael

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)

0
Ashish K Srivastava

Suppression de _\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 .


Avec 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
_

Avec tr:

Une autre option est tr :

_tr -d '\r' < input > output
_

Différence entre 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.


Essai:

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
% 
_
0
cnst