web-dev-qa-db-fra.com

Comment supprimer la première colonne (qui est en fait des noms de lignes) d'un fichier de données sous Linux?

J'ai un fichier de données avec plusieurs milliers de colonnes et de lignes. Je veux supprimer la première colonne qui est en fait le compteur de lignes. J'ai utilisé cette commande sous linux:

cut -d " " -f 2- input.txt > output.txt

mais rien n'a changé dans ma sortie. Est-ce que quelqu'un sait pourquoi cela ne fonctionne pas et que dois-je faire?

Voici à quoi ressemble mon fichier d'entrée:

col1 col2 col3 col4 ...
     1 0 0 0 1
     2 0 1 0 1
     3 0 1 0 0
     4 0 0 0 0 
     5 0 1 1 1 
     6 1 1 1 0
     7 1 0 0 0 
     8 0 0 0 0
     9 1 0 0 0
     10 1 1 1 1
     11 0 0 0 1
    .
    .
    .

Je veux que ma sortie ressemble à ceci:

col1 col2 col3 col4 ...
0 0 0 1
0 1 0 1
0 1 0 0
0 0 0 0 
0 1 1 1 
1 1 1 0
1 0 0 0 
0 0 0 0
1 0 0 0
1 1 1 1
0 0 0 1
.
.
.

J'ai également essayé la commande sed:

 sed '1d' input.file > output.file

Mais il supprime la première ligne et non la première colonne.

Quelqu'un pourrait-il me guider?

16
zara

@Karafka J'avais des fichiers CSV alors j'ai ajouté le séparateur "," (vous pouvez le remplacer par le vôtre

cut -d"," -f2- input.csv  > output.csv

Ensuite, j'ai utilisé une boucle pour parcourir tous les fichiers du répertoire

# files are in the directory tmp/
for f in tmp/*
do
    name=`basename $f`
    echo "processing file : $name"
    #kepp all column excep the first one of each csv file 

    cut -d"," -f2- $f > new/$name
    #files using the same names are stored in directory new/  
done
6
Fouad Djebbar

l'utilisation idiomatique de la coupe sera

cut -f2- input > output

si votre délimiteur est tab ("\ t").

Ou, simplement avec awk magic (fonctionnera à la fois pour l'espace et le délimiteur de tabulation)

 awk '{$1=""}1' input | awk '{$1=$1}1' > output

le premier awk supprimera le champ 1, mais laisse un délimiteur, le deuxième awk supprime le délimiteur. Le délimiteur de sortie par défaut sera l'espace, si vous souhaitez passer à l'onglet, ajoutez -vOFS="\t" au deuxième awk.

MIS À JOUR

Sur la base de votre entrée mise à jour, le problème est les espaces initiaux qui coupent les friandises en plusieurs colonnes. Une façon de les résoudre consiste à les retirer avant de les nourrir pour les couper.

sed 's/^ *//' input | cut -d" " -f2- > output

ou utilisez l'alternative awk ci-dessus qui fonctionnera également dans ce cas.

15
karakfa

Vous pouvez utiliser la commande cut avec --complement option:

cut -f1 -d" " --complement input.file > output.file

Cela affichera toutes les colonnes sauf la première.

13
buff

Comme le note @karakfa, il semble que ce soit le premier espace blanc à l'origine de vos problèmes.

Voici un sed oneliner pour faire le travail (qui tiendra compte des espaces ou des tabulations):

sed -i.bak "s|^[ \t]\+[0-9]\+[ \t]\+||" input.txt

Explication:

-i       edit existing file in place
.bak     backup original file and add .bak file extension (can use whatever you like)

s        substitute
|        separator (easiest character to read as sed separator IMO)
^        start match at start of the line
[ \t]    match space or tab
\+       match one or more times (escape required so sed does not interpret '+' literally)
[0-9]    match any number 0 - 9

Comme indiqué; le input.txt le fichier sera édité sur place. Le contenu original de input.txt sera enregistré sous input.txt.bak. Utilisez simplement -i à la place si vous ne voulez pas de sauvegarde du fichier d'origine.

De plus, si vous savez qu'il s'agit bien d'espaces de tête (et non de tabulations), vous pouvez le raccourcir comme suit:

sed -i.bak "s|^ \+[0-9]\+[ \t]\+||" input.txt
0
Jeremy Davis

Vous pouvez également y parvenir avec grep:

grep -E -o '[[:digit:]]([[:space:]][[:digit:]]){3}$' input.txt

Ce qui suppose un chiffre à un caractère et des colonnes d'espace. Pour accueillir un nombre variable d'espaces et de chiffres, vous pouvez:

grep -E -o '[[:digit:]]+([[:space:]]+[[:digit:]]+){3}$' input.txt

Si votre grep prend en charge le -P drapeau (--Perl-regexp) tu peux faire:

grep -P -o '\d+(\s+\d+){3}$' input.txt

Et voici quelques options si vous utilisez GNU sed:

sed 's/^\s\+\w\+\s\+//' input.txt
sed 's/^\s\+\S\+\s\+//' input.txt
sed 's/^\s\+[0-9]\+\s\+//' input.txt
sed 's/^\s\+[[:digit:]]\+\s\+//' input.txt

Notez que les expressions rationnelles grep correspondent aux parties que nous voulons conserver tandis que les expressions rationnelles sed correspondent aux parties que nous voulons supprimer.

0
htaccess