Supprimer le retour chariot dans Unix

Réponses:

261

Je vais supposer que vous moyenne des retours chariot ( CR, "\r", 0x0d) aux extrémités des lignes plutôt que aveuglément dans un fichier (vous pouvez les avoir au milieu des cordes 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 à parcourir 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, vous n'êtes pas disponible, vous sedle ferez:

$ 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, vous n'êtes pas disponible, alors edle ferez, 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 aucun de ces outils n'est installé sur votre box, vous avez de plus gros problèmes que d'essayer de convertir des fichiers :-)

paxdiablo
la source
13
\rne fonctionne qu'avec GNU sed, sinon vous pouvez le faire:sed `echo "s/\r//"`
lapo
15
Ni sedni echoreconnaître \rsur MacOs. Dans ce cas, cela ne printf "\r"semble fonctionner.
Steve Powell
30
Pour développer le commentaire de @ steve: Sur un Mac, utilisez ce qui suit: sed "s/$(printf '\r')\$//"
mklement0
7
Pour résoudre le problème sur mac, vous pouvez également préfixer la chaîne sed entre guillemets $comme ceci: sed $'s@\r@@g' |od -c (mais si vous le remplacez, \nvous devrez l'échapper)
nhed
1
Je ne suis pas sûr à 100%, mais pour OS X, utiliser CTRL-V + CTRL-Mà la place de \rcela pourrait fonctionner.
240
tr -d '\r' < infile > outfile

Voir tr (1)

Henrik Gustafsson
la source
4
Pas génial: 1. ne fonctionne pas sur place, 2. peut remplacer \ r également pas à EOL (qui peut ou non être ce que vous voulez ...).
Tomasz Gandor
10
1. La plupart des outils Unixy fonctionnent de cette façon, et c'est généralement la façon la plus sûre de faire les choses, car si vous bousillez, vous avez toujours l'original. 2. La question posée est de supprimer les retours chariot et non de convertir les fins de ligne. Mais il existe de nombreuses autres réponses qui pourraient mieux vous servir.
Henrik Gustafsson
1
Si votre trne prend pas en charge l' \réchappement, essayez '\015'ou peut-être un littéral '^M'(dans de nombreux shells sur de nombreux terminaux, ctrl-V ctrl-M produira un caractère littéral ctrl-M).
tripleee
Alors, comment peut-on le changer quand on veut outfile = infile?
Christopher
3
@donlan, réponse tardive , mais vous utilisez habituellement quelque chose comme: someProg <in >out && mv out in.
paxdiablo
38

Vieille école:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
socle
la source
32

Le moyen le plus simple sous Linux est, à mon humble avis,

sed -i 's/\r$//g' <filename>

Les citations fortes autour de l'opérateur de substitution 's/\r//'sont essentielles . Sans eux, le shell interprétera \rcomme un escape + r et le réduira à une plaine 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 l'ajout du /gmodificateur garantit que même plusieurs \rseront supprimés, et pas seulement le premier.

wfjm
la source
27

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

Emil H
la source
6
Parfois, il est également appelé fromdos (et todos).
Anonyme
Le lien est maintenant
fermé
7

sed -i s/\r// <filename>ou quelque chose comme ça; voir man sedou la richesse des informations disponibles sur le Web concernant l'utilisation de sed.

Une chose à souligner est la signification précise de "retour chariot" dans ce qui précède; si vous voulez vraiment dire le caractère de contrôle unique "retour chariot", alors le modèle ci-dessus est correct. Si vous vouliez dire, plus généralement, CRLF (retour chariot et un saut de ligne, qui est la façon dont les sauts de ligne sont implémentés sous Windows), alors vous voudrez probablement le remplacer à la \r\nplace. Les sauts de ligne nus (newline) sous Linux / Unix le sont \n.

Rob
la source
J'essaie d'utiliser -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt qui ne fonctionne pas. "tigre" "Lion".
Suvasis
devons-nous considérer que vous êtes sur un Mac? J'ai remarqué que Darwin sed semble avoir des commandes et des fonctionnalités différentes par défaut que la plupart des versions de Linux ...
jsh
4
Pour info, le s/\r//ne semble pas supprimer les retours chariot sur OS X, il semble supprimer les rcaractères littéraux à la place. Je ne sais pas encore pourquoi. Peut-être que cela a quelque chose à voir avec la façon dont la chaîne est citée? Comme solution de contournement, l'utilisation CTRL-V + CTRL-Mà la place de \rsemble fonctionner.
6

Si vous êtes un utilisateur 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.

Alex Giotis
la source
2
Pas génial: si le fichier a CR sur chaque ligne (c'est-à-dire un fichier DOS correct), vim le chargera avec filetype = dos, et ne montrera pas du tout ^M-s. Contourner cela est une tonne de frappes, ce qui n'est pas ce pour quoi Vim est fait;). J'irais juste pour sed -i, puis `-e 's / \ r $ // g' pour limiter la suppression aux CR à EOL.
Tomasz Gandor
6

Une fois de plus une solution ... Parce qu'il y en a toujours une de plus:

perl -i -pe 's/\r//' filename

C'est bien parce qu'il est en place et fonctionne dans toutes les saveurs d'Unix / Linux avec lesquelles j'ai travaillé.

Allan Cano
la source
3

Quelqu'un d'autre le recommande dos2unixet je le recommande fortement également. Je fournis juste plus de détails.

S'il est installé, passez à l'étape suivante. S'il n'est pas déjà installé, je recommanderais de l'installer via yumcomme:

yum install dos2unix

Ensuite, vous pouvez l'utiliser comme:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
James Oravec
la source
2

Si vous utilisez un OS (comme OS X) qui n'a pas la dos2unixcommande mais qui a un interpréteur Python (version 2.5+), cette commande est équivalente à la dos2unixcommande:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Cela gère les fichiers nommés sur la ligne de commande ainsi que les canaux et les redirections, tout comme dos2unix. Si vous ajoutez cette ligne à votre fichier ~ / .bashrc (ou 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 ~/.bashrcdans la session en cours), vous pourrez utiliser le dos2unixnom sur la ligne de commande de la même manière que dans les autres exemples.

Chris Johnson
la source
2

Voici la chose,

%0dest le caractère de retour chariot. Pour le rendre compatible avec Unix. Nous devons utiliser la commande ci-dessous.

dos2unix fileName.extension fileName.extension

Sireesh Yarlagadda
la source
1

essayez ceci pour convertir le fichier dos en fichier unix:

fichier fromdos

Hawston
la source
1

Pour UNIX ... J'ai remarqué que dos2unix a 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 chariot à la fin des lignes et préserve les en-têtes Unicode.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
LexieHankins
la source
1

Si vous utilisez un environnement X et disposez d'un éditeur approprié (code Visual Studio), je suivrais la recommandation:

Code Visual Studio: comment afficher les fins de ligne

Il suffit d'aller dans le coin inférieur droit de votre écran, le code de Visual Studio vous montrera à la fois l'encodage du fichier et la convention de fin de ligne suivie par le fichier, un simple clic vous permet de changer cela.

Utilisez simplement du code visuel pour remplacer notepad ++ sur un environnement Linux et vous êtes prêt à partir.

99Sono
la source
Ou utilisez Notepad++la commande de Edit / EOL Conversion / Unix (LF)sur votre système Windows avant de copier le fichier sur votre système Linux.
Jesse Chisholm
1

Suppression \rsur n'importe quel système UNIX®:

La plupart des solutions existantes dans cette question sont spécifiques à GNU et ne fonctionneraient pas sur OS X ou BSD; les solutions ci-dessous devraient fonctionner sur de nombreux autres systèmes UNIX, et dans n'importe quel shell, de tcshà sh, tout en fonctionnant même sur GNU / Linux.

Testé sur OS X, OpenBSD et NetBSD dans tcsh, et sur Debian GNU / Linux dans bash.


Avec sed:

Dans tcshun OS X, l' sedextrait de code suivant pourrait être utilisé avec printf, comme ni sedni echogérer \rde la manière spéciale comme le fait GNU:

sed `printf 's/\r$//g'` input > output

Avec tr:

Une autre option est tr:

tr -d '\r' < input > output

Différence entre sedet tr:

Il semblerait que trconserve un manque de retour à la ligne de fin du fichier d'entrée, alors que sedsur OS X et NetBSD (mais pas sur OpenBSD ou GNU / Linux) insère un retour à la ligne à la fin du fichier même si l'entrée manque à la fin \rou \nà la toute fin du fichier.


Essai:

Voici quelques exemples de tests qui pourraient être utilisés pour s'assurer que cela fonctionne sur votre système, en utilisant printfet hexdump -C; alternativement, od -cpourrait également être utilisé si votre système est manquant 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
% 
cnst
la source
0

J'ai utilisé python pour ça, ici 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)
Raphael
la source
0

Bien que ce soit un post plus ancien, je suis récemment tombé sur le même problème. Comme j'avais tous les fichiers à renommer dans / tmp / blah_dir / car chaque fichier dans ce répertoire avait un caractère de fin "/ r" (montrant "?" À la fin du fichier), donc le faire de manière script était la seule chose à laquelle je pouvais penser.

Je voulais enregistrer le fichier final avec le même nom (sans laisser de caractère). Avec sed, le problème était le nom du fichier de sortie dont j'avais besoin pour mentionner autre chose (dont je ne voulais pas).

J'ai essayé d'autres options comme suggéré ici (non considéré comme dos2unix en raison de certaines limitations) mais je n'ai pas fonctionné.

J'ai finalement essayé avec "awk" qui fonctionnait là où j'ai utilisé "\ r" comme délimiteur et pris la première partie :

l'astuce est:

echo ${filename}|awk -F"\r" '{print $1}'

Ci-dessous l'extrait de script que j'ai utilisé (où j'avais tout le fichier avait "\ r" comme caractère de fin dans path / 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

Remarque: Cet exemple n'est pas très exact mais proche de ce que j'ai travaillé (mentionner ici juste pour donner une meilleure idée de ce que j'ai fait)

Ashish K Srivastava
la source
0

J'ai fait ce shell-script pour supprimer le caractère \ r. Il fonctionne en solaris et red-hat:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0
Heloderma Suspectum
la source
-1

vous pouvez simplement faire ceci:

$ echo $(cat input) > output
mma7
la source
Je ne sais pas pourquoi quelqu'un a donné «-1». C'est une très bonne réponse (et la seule qui a fonctionné pour moi).
FractalSpace
1
Oh, désolé, c'était moi. Attendez, regardez, ça ne fonctionne vraiment pas pour '\ r'!
Viacheslav Rodionov
1
@FractalSpace C'est une terrible idée! Il détruit complètement tout l'espacement dans le fichier et laisse tout le contenu du fichier sujet à interprétation par le shell. Essayez-le avec un fichier qui contient une ligne a * b...
Tom Fenech