J'ai un fichier avec plusieurs lignes Dans chaque ligne, il y a plusieurs colonnes (champs) séparées par des "" Les nombres de colonnes dans chaque ligne sont différents Je veux supprimer les deux premières colonnes comment?
Vous pouvez le faire avec cut
:
cut -d " " -f 3- input_filename > output_filename
Explication:
cut
: invoquer la commande cut-d " "
: utilise un seul espace comme délimiteur (cut
utilise TAB par défaut)-f
: spécifier les champs à conserver3-
: tous les champs commençant par le champ 3input_filename
: utilise ce fichier comme entrée> output_filename
: écrivez le résultat dans ce fichier.Sinon, vous pouvez le faire avec awk
:
awk '{$1=""; $2=""; sub(" ", " "); print}' input_filename > output_filename
Explication:
awk
: invoquer la commande awk$1=""; $2="";
: définit les champs 1 et 2 sur la chaîne videsub(...);
: nettoie les champs de sortie car les champs 1 et 2 seront toujours délimités par ""print
: affiche la ligne modifiéeinput_filename > output_filename
: comme ci-dessus.Voici une façon de le faire avec Awk qui est relativement facile à comprendre:
awk '{print substr($0, index($0, $3))}'
Il s'agit d'une simple commande awk sans motif, de sorte que l'action à l'intérieur de {}
est exécutée pour chaque ligne d'entrée.
L'action consiste à simplement imprimer la sous-chaîne en commençant par la position du troisième champ.
$0
: toute la ligne de saisie$3
: 3ème champindex(in, find)
: renvoie la position de find
dans la chaîne in
substr(string, start)
: retourne une sous-chaîne commençant à index start
Si vous souhaitez utiliser un autre délimiteur, tel que la virgule, vous pouvez le spécifier avec l'option -F:
awk -F"," '{print substr($0, index($0, $3))}'
Vous pouvez également utiliser cette option sur un sous-ensemble des lignes d'entrée en spécifiant un modèle avant l'action dans {}
. Seules les lignes correspondant au motif font exécuter l'action.
awk 'pattern{print substr($0, index($0, $3))}'
Où motif peut être quelque chose comme:
/abcdef/
: utilise une expression régulière, fonctionne sur $ 0 par défaut.$1 ~ /abcdef/
: opère sur un champ spécifique.$1 == blabla
: utiliser la comparaison de chaînesNR > 1
: utilise le numéro d'enregistrement/ligneNF > 0
: utiliser le numéro de champ/colonneMerci d'avoir posté la question. J'aimerais aussi ajouter le script qui m'a aidé.
awk '{ $1=""; print $0 }' file
awk '{$1=$2="";$0=$0;$1=$1}1'
Contribution
a b c d
Sortie
c d
C'est assez simple de le faire avec seulement Shell
while read A B C; do
echo "$C"
done < oldfile >newfile
Vous pouvez utiliser sed
:
sed 's/^[^ ][^ ]* [^ ][^ ]* //'
Ceci recherche les lignes commençant par un ou plusieurs non-blancs, un blanc, un autre ensemble de un ou plusieurs non-blancs et un autre blanc, et supprime le matériau correspondant, c'est-à-dire les deux premiers champs. Le [^ ][^ ]*
est légèrement plus court que la notation [^ ]\{1,\}
équivalente mais plus explicite, et le second risque de rencontrer des problèmes avec GNU sed
(bien que si vous utilisez --posix
en tant qu'option, même GNU sed
ne peut pas le vider up). OTOH, si la classe de caractères à répéter était plus complexe, la notation numérotée gagne par souci de concision. Il est facile d’étendre cette option pour traiter "espace ou tabulation" comme séparateur, ou "plusieurs espaces" ou "plusieurs espaces ou onglets". Il peut également être modifié pour gérer des espaces (ou des onglets) facultatifs précédant le premier champ, etc.
Pour awk
et cut
, voir Sampson-Chen 's answer . Il existe d'autres moyens d'écrire le script awk
, mais ils ne sont pas matériellement meilleurs que la réponse fournie. Notez que vous devrez peut-être définir le séparateur de champ explicitement (-F" "
) dans awk
si vous ne souhaitez pas que les onglets soient traités comme des séparateurs, ou vous pouvez avoir plusieurs espaces entre les champs. La norme POSIX cut
ne prend pas en charge plusieurs séparateurs entre les champs; GNU cut
a l'option -i
utile mais non standard pour autoriser plusieurs séparateurs entre les champs.
Vous pouvez aussi le faire en pur Shell:
while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
Perl:
Perl -lane 'print join(' ',@F[2..$#F])' File
awk:
awk '{$1=$2=""}1' File
Cela pourrait fonctionner pour vous (GNU sed):
sed -r 's/^([^ ]+ ){2}//' file
ou pour les colonnes séparées par un ou plusieurs espaces blancs:
sed -r 's/^(\S+\s+){2}//' file
Utilisez kscript
kscript 'lines.split().select(-1,-2).print()' file