Remplacer les espaces par des tabulations sous Linux

98

Comment remplacer les espaces par des tabulations sous Linux dans un fichier texte donné?

biznez
la source

Réponses:

168

Utilisez le programme unxpand (1)


UNEXPAND(1)                      User Commands                     UNEXPAND(1)

NAME
       unexpand - convert spaces to tabs

SYNOPSIS
       unexpand [OPTION]... [FILE]...

DESCRIPTION
       Convert  blanks in each FILE to tabs, writing to standard output.  With
       no FILE, or when FILE is -, read standard input.

       Mandatory arguments to long options are  mandatory  for  short  options
       too.

       -a, --all
              convert all blanks, instead of just initial blanks

       --first-only
              convert only leading sequences of blanks (overrides -a)

       -t, --tabs=N
              have tabs N characters apart instead of 8 (enables -a)

       -t, --tabs=LIST
              use comma separated LIST of tab positions (enables -a)

       --help display this help and exit

       --version
              output version information and exit
. . .
STANDARDS
       The expand and unexpand utilities conform to IEEE Std 1003.1-2001
       (``POSIX.1'').
DigitalRoss
la source
4
Woah, je n'ai jamais su que l'expansion / la désexpansion existait. J'essayais de faire le contraire et étendre était parfait plutôt que d'avoir à jouer avec trou sed.
Ibrahim
4
Pour mémoire, expand / unxpand sont des utilitaires standard .
kojiro
4
Tellement cool que ce sont des standards. J'adore la philosophie UNIX . Ce serait bien si cela pouvait être mis en place.
Matthew Flaschen
3
Je ne pense pas qu'unexpand fonctionnera ici .. il ne convertit que les espaces de début
olala
13
Juste une mise en garde - unxpand ne convertira pas un seul espace en onglet. Si vous devez convertir aveuglément toutes les séries de caractères 0x20 en un seul onglet, vous avez besoin d'un outil différent.
Steve S.
44

Je pense que tu peux essayer avec awk

awk -v OFS="\t" '$1=$1' file1

ou SED si vous préférez

sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt

ou même tr

tr -s '\t' < thefile.txt | tr '\t' ' ' > the_modified_copy.txt

ou une version simplifiée de la solution tr proposée par Sam Bisbee

tr ' ' \\t < someFile > someFile
Jonathan
la source
4
Dans votre exemple sed, les meilleures pratiques vous dictent d'utiliser tr pour remplacer des caractères uniques par rapport à sed pour des raisons d'efficacité / vitesse. De plus, l'exemple de tr est beaucoup plus facile de cette façon:tr ' ' \\t < someFile > someFile
Sam Bisbee
2
Bien sûr, tr a de meilleures performances que sed, mais la principale raison pour laquelle j'aime Unix est qu'il existe de nombreuses façons de faire quelque chose. Si vous envisagez de faire cette substitution plusieurs fois, vous chercherez une solution avec de bonnes performances, mais si vous ne le faites qu'une seule fois, vous rechercherez une solution qui implique une commande qui vous mettra à l'aise.
Jonathan le
2
arg. J'ai dû utiliser des essais et des erreurs pour faire fonctionner le sed. Je ne sais pas pourquoi j'ai dû échapper au signe plus comme ceci:ls -l | sed "s/ \+/ /g"
Jess
Avec awk -v OFS="\t" '$1=$1' file1j'ai remarqué que si vous avez une ligne commençant par le numéro 0 (par exemple 0 1 2), la ligne sera supprimée du résultat.
Nikola Novak le
@Jess Vous avez trouvé l'expression rationnelle «syntaxe par défaut correcte». Par défaut, sed traite le signe plus simple (sans échappement) comme un caractère simple. La même chose est vraie pour certains autres caractères comme «?», ... Vous pouvez trouver plus d'informations ici: gnu.org/software/sed/manual/html_node/… . Des détails de syntaxe similaires peuvent être trouvés ici (notez qu'il s'agit de man pour grep, pas de sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Victor Yarema
11

Utilisation de Perl :

perl -p -i -e 's/ /\t/g' file.txt
John Millikin
la source
3
Eu un problème similaire avec le remplacement des espaces consécutifs par un seul onglet. Perl fonctionnait avec seulement l'ajout d'un «+» à l'expression rationnelle.
Todd
Bien sûr, je voulais faire le contraire: convertir les tabulations en deux espaces:perl -p -i -e 's/\t/ /g' *.java
TimP
Puis-je faire cela de manière récursive?
Aaron Franke du
10

meilleure commande tr :

tr [:blank:] \\t

Cela nettoiera la sortie de disons, unzip -l , pour un traitement ultérieur avec grep, cut, etc.

par exemple,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Tarkin
la source
Je n'ai pas besoin d'utiliser des guillemets pour que cela fonctionne:tr [:blank:] \\t
Ömer An
3

Téléchargez et exécutez le script suivant pour convertir de manière récursive les onglets logiciels en onglets fixes dans des fichiers de texte brut.

Placez et exécutez le script à partir du dossier contenant les fichiers de texte brut.

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(unexpand --first-only -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;
daka
la source
2

Exemple de commande pour convertir chaque fichier .js sous le répertoire courant en tabulations (seuls les espaces de début sont convertis):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
Arkod
la source
Testé en cygwin sur Windows 7.
Arkod
1

Vous pouvez également utiliser astyle. Je l'ai trouvé assez utile et il a aussi plusieurs options:

Tab and Bracket Options:
   If  no  indentation  option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4.  If no brackets option is set, the
   brackets will not be changed.

   --indent=spaces, --indent=spaces=#, -s, -s#
          Indent using # spaces per indent. Between 1 to 20.  Not specifying # will result in a default of 4 spaces per indent.

   --indent=tab, --indent=tab=#, -t, -t#
          Indent using tab characters, assuming that each tab is # spaces long.  Between 1 and 20. Not specifying # will result in a default assumption  of
          4 spaces per tab.`
Ankur Agarwal
la source
0

Si vous parlez de remplacer tous les espaces consécutifs sur une ligne par une tabulation, alors tr -s '[:blank:]' '\t'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda
Device         Start
/dev/sda1       2048
/dev/sda2     411648
/dev/sda3    2508800
/dev/sda4   10639360
/dev/sda5   75307008
/dev/sda6   96278528
/dev/sda7  115809778
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t'
Device  Start
/dev/sda1       2048
/dev/sda2       411648
/dev/sda3       2508800
/dev/sda4       10639360
/dev/sda5       75307008
/dev/sda6       96278528
/dev/sda7       115809778

Si vous parlez de remplacer tous les espaces (par exemple, espace, tabulation, nouvelle ligne, etc.), alors tr -s '[:space:]'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t'
Device  Start   /dev/sda1       2048    /dev/sda2       411648  /dev/sda3       2508800 /dev/sda4       10639360        /dev/sda5       75307008        /dev/sda6     96278528        /dev/sda7       115809778  

Si vous parlez de réparer un fichier endommagé par des onglets, utilisez expandet unexpandcomme mentionné dans d'autres réponses.

musaraigne
la source
0

Utilisation de sed :

T=$(printf "\t")
sed "s/[[:blank:]]\+/$T/g"

ou

sed "s/[[:space:]]\+/$T/g"
Tibor
la source
-1

Cela remplacera les espaces consécutifs par un espace (mais pas une tabulation).

tr -s '[:blank:]'

Cela remplacera les espaces consécutifs par une tabulation.

tr -s '[:blank:]' '\t'
mel
la source
En fait, -cil remplace les caractères consécutifs qui ne sont pas des espaces.
wingedsubmariner
1
La question concerne les onglets, ce n'est pas une réponse.
Matthew Lire le