Quelle est la façon la plus simple de supprimer tous les retours chariot \r
d'un fichier sous Unix?
Quelle est la façon la plus simple de supprimer tous les retours chariot \r
d'un fichier sous Unix?
Réponses:
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 sed
le 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 ed
le 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 :-)
\r
ne fonctionne qu'avec GNU sed, sinon vous pouvez le faire:sed `echo "s/\r//"`
sed
ni echo
reconnaître \r
sur MacOs. Dans ce cas, cela ne printf "\r"
semble fonctionner.
sed "s/$(printf '\r')\$//"
$
comme ceci: sed $'s@\r@@g' |od -c
(mais si vous le remplacez, \n
vous devrez l'échapper)
tr -d '\r' < infile > outfile
Voir tr (1)
tr
ne 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).
outfile = infile
?
someProg <in >out && mv out in
.
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 \r
comme 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 /g
modificateur 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 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\n
place. Les sauts de ligne nus (newline) sous Linux / Unix le sont \n
.
s/\r//
ne semble pas supprimer les retours chariot sur OS X, il semble supprimer les r
caractè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 \r
semble fonctionner.
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.
^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.
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é.
Quelqu'un d'autre le recommande dos2unix
et 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 yum
comme:
yum install dos2unix
Ensuite, vous pouvez l'utiliser comme:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Si vous utilisez un OS (comme OS X) qui n'a pas la dos2unix
commande mais qui a un interpréteur Python (version 2.5+), cette commande est équivalente à la dos2unix
commande:
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 ~/.bashrc
dans la session en cours), vous pourrez utiliser le dos2unix
nom sur la ligne de commande de la même manière que dans les autres exemples.
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 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"
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.
Notepad++
la commande de Edit / EOL Conversion / Unix (LF)
sur votre système Windows avant de copier le fichier sur votre système Linux.
\r
sur 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
.
sed
:Dans tcsh
un OS X, l' sed
extrait de code suivant pourrait être utilisé avec printf
, comme ni sed
ni echo
gérer \r
de la manière spéciale comme le fait 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
conserve un manque de retour à la ligne de fin du fichier d'entrée, alors que sed
sur 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 \r
ou \n
à la toute fin du fichier.
Voici quelques exemples de tests qui pourraient être utilisés pour s'assurer que cela fonctionne sur votre système, en utilisant printf
et hexdump -C
; alternativement, od -c
pourrait é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
%
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)
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
vous pouvez simplement faire ceci:
$ echo $(cat input) > output
a * b
...