Entfernen von Erweiterungen in einer Spalte

Entfernen von Erweiterungen in einer Spalte

Ich habe eine Datei wie diese

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402.5
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046.3
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838.1

Ich möchte die numerischen Erweiterungen am Ende der 3. Spalte entfernen, damit meine Ausgabedatei so aussieht

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

Wie kann ich dies in der Befehlszeile tun, vorzugsweise mit awk? Ich kann dies in tun, perlaber ich bin ziemlich sicher, dass es dafür eine einzige Befehlszeile gibt.

Antwort1

Mit awk:

awk -F'.' '{print $1}' file

-FOption: Standard-Feldtrennzeichen (Leerzeichen) in Punkt (.) ändern.
$1ist der Index der Feldposition (mit . Feldtrennzeichen).

{ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402}.{5}
                  ^^ field index is $1                                          ^^$2

Mit rev und awk:

rev file | awk -F'.' '{print $2}'|rev # reverse characters of each lines,\
                                        print field number 2 with (.) separator \
                                        and reverse the result again

Das revDienstprogramm kopiert die angegebenen Dateien in die Standardausgabe und kehrt dabei die Reihenfolge der Zeichen in jeder Zeile um. Wenn keine Dateien angegeben sind, wird die Standardeingabe gelesen.

Mit sed:

sed 's/.[0-9]*$//' file

sed 's/.[^.]*$//' file

$Zeigen Sie auf das Zeilenende. Suchen Sie im ersten sed-Befehl nach Zeichen (.), auf das null oder mehr Zahlen folgen, und ersetzen Sie diese durch Leerzeichen.

Entfernen Sie im zweiten sed-Befehl alles, worauf ein (.) folgt, und entfernen Sie auch den Punkt (.) selbst.

Mit rev und sed:

rev file| sed 's/.*[.]//' |rev

Löschen Sie alles vor dem Punkt (.). Schließen Sie auch . selbst ein und entfernen Sie es.

Mit grep:

grep -oP '.*(?=\.[0-9])' file
    -o, --only-matching
          Drucken Sie nur die übereinstimmenden (nicht leeren) Teile einer übereinstimmenden Zeile.
          wobei sich jeder dieser Teile auf einer separaten Ausgabeleitung befindet.
    -P, --perl-regexp
          Interpretieren Sie PATTERN als Perl-kompatiblen regulären Ausdruck (PCRE).

(?=pattern): Positiver Lookahead: Die positive Lookahead-Konstruktion besteht aus einem Paar Klammern, wobei auf die öffnende Klammer ein Fragezeichen und ein Gleichheitszeichen folgen.

.*(?=\.[0-9]): (positiver Vorausblick) passt zu allem( .*), gefolgt von einem Punkt(.) und allen Vorkommen von Zahlen, ohne das Muster( \.[0-9]) in die Übereinstimmung einzubeziehen.

Mit rev und grep:

rev file |grep -oP '(?<=[0-9]\.).*' |rev

rev file |grep -oP '[0-9]\.\K.*' |rev

(?<=pattern): Positiver Lookbehind. Ein Paar Klammern, wobei auf die öffnende Klammer ein Fragezeichen, ein „Kleiner-als“-Symbol und ein Gleichheitszeichen folgen.

(?<=[0-9]\.).*(positiver Lookbehind) passt zu allem, worauf beliebige Zahlen folgen und was mit einem Punkt (.) endet.

Im zweiten Grep-Befehl können Sie Nifty \Kanstelle der Lookbehind-Assertion verwenden.

Mit Schnitt:

cut -f1 -d. file

cut -c 1-77 file # Print first 77 characters of each line.
Ausschneiden - Abschnitte aus jeder Dateizeile entfernen

-d, --delimiter=DELIM
      Verwenden Sie DELIM statt TAB als Feldtrennzeichen

-f, --fields=LISTE
      Wählen Sie nur diese Felder aus;

-c, --characters=LISTE
      Wählen Sie nur diese Zeichen aus

Mit while-Schleife:

while read line; do echo "${line::-2}";done <file

Dies funktioniert, wenn Sie am Ende jeder Zeile nur Zahlen mit der Länge 1 haben und diese eine feste Länge haben. Der obige Befehl entfernt die letzten beiden Zeichen am Ende jeder Zeile in der Eingabedatei. Alternative Befehle sind ${line%??}:

Antwort2

Angenommen, die Erweiterungen sind ausschließlich Ziffern:

perl -pi -e 's/\.\d+$//' /path/to/file

-iführt die Bearbeitung direkt durch (wie in sed). \dbedeutet Ziffern und $kennzeichnet das Zeilenende.

Mit awk:

awk 'gsub(/\.[0-9]+$/,"")' /path/to/file

gawkhat in neueren Versionen eine Option zur direkten Bearbeitung, aber ich bin nicht sicher, wie portabel diese ist. gsubunterstützt einen optionalen Parameter, der die Zielspalte angibt:

awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file

Die letzte Form hat den unerwünschten Nebeneffekt, dass in der Ausgabe jede Spalte durch ein einzelnes Leerzeichen getrennt wird, als ob Sie Folgendes getan hätten print $1,..,$NF. Ich weiß nicht, warum.

Antwort3

Die Verwendung awkist unkompliziert. Legen Sie Ihren Feldtrenner einfach wie folgt fest .:

awk -F. '{print $1}' file

Ein anderer Ansatz unter Verwendung der Shell (in diesem Fall Bash):

while IFS=.; read -r lines _; do  line+=("$lines"); done <file                                                                           
printf "%s\n" "${line[@]}"
ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

Antwort4

Dadurch wird alles entfernt, was mit dem Punkt beginnt:

sed 's/\..*//'

verwandte Informationen