
tengo un archivo como este
ILMN_1343291 TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG NM_001402.5
ILMN_1343295 CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG NM_002046.3
ILMN_1651209 TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC NM_182838.1
Quiero eliminar las extensiones numéricas del final de la tercera columna para que mi archivo de salida se vea así
ILMN_1343291 TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG NM_001402
ILMN_1343295 CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG NM_002046
ILMN_1651209 TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC NM_182838
¿Cómo puedo hacerlo en la línea de comando, preferiblemente usando awk
? Puedo hacer esto, perl
pero estoy bastante seguro de que hay una única línea de comando para hacerlo.
Respuesta1
Con awk:
awk -F'.' '{print $1}' file
-F
opción cambia el separador de campo predeterminado (espacio) a punto (.).
$1
es el índice de la posición del campo (con separador de campo).
{ILMN_1343291 TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG NM_001402}.{5}
^^ field index is $1 ^^$2
Con rev y awk:
rev file | awk -F'.' '{print $2}'|rev # reverse characters of each lines,\
print field number 2 with (.) separator \
and reverse the result again
La rev
utilidad copia los archivos especificados en la salida estándar, invirtiendo el orden de los caracteres en cada línea. Si no se especifica ningún archivo, se lee la entrada estándar.
Con asiento:
sed 's/.[0-9]*$//' file
sed 's/.[^.]*$//' file
$
apuntar al final de la línea. En el primer comando sed, busque char(.) seguido de cero o más apariciones de números y reemplácelos con espacios en blanco.
En el segundo comando sed, elimine todo lo que sigue a (.) y también elimine el punto (.).
Con rev y sed:
rev file| sed 's/.*[.]//' |rev
Elimine todo lo que esté antes del punto (.) También incluya y elimine . sí mismo.
Con grep:
grep -oP '.*(?=\.[0-9])' file
-o, --solo-coincidencia Imprima solo las partes coincidentes (no vacías) de una línea coincidente, con cada una de estas partes en una línea de salida separada. -P, --perl-regexp Interpretar PATTERN como una expresión regular compatible con Perl (PCRE)
(?=pattern)
: Previsión positiva: la construcción de anticipación positiva es un par de paréntesis, con el paréntesis de apertura seguido de un signo de interrogación y un signo igual.
.*(?=\.[0-9])
: (búsqueda positiva) coincide con todo( .*
) seguido de un punto(.) y cualquier aparición de números, sin que el patrón( \.[0-9]
) forme parte de la coincidencia.
Con rev y grep:
rev file |grep -oP '(?<=[0-9]\.).*' |rev
rev file |grep -oP '[0-9]\.\K.*' |rev
(?<=pattern)
: Búsqueda atrás positiva. Un par de paréntesis, con el paréntesis inicial seguido de un signo de interrogación, un símbolo "menor que" y un signo igual.
(?<=[0-9]\.).*
(mirada hacia atrás positiva) coincide con todo lo que sigue a cualquier aparición de números y termina con un punto (.).
En el segundo comando grep, puede usar nifty \K
en lugar de la aserción de búsqueda hacia atrás.
Con corte:
cut -f1 -d. file
cut -c 1-77 file # Print first 77 characters of each line.
cortar: eliminar secciones de cada línea de archivos -d, --delimitador=DELIM use DELIM en lugar de TAB para delimitador de campo -f, --campos=LISTA seleccione sólo estos campos; -c, --caracteres=LISTA seleccione solo estos personajes
Con bucle while:
while read line; do echo "${line::-2}";done <file
Esto funcionará si solo tiene un número con longitud = 1 al final de cada línea y tienen una longitud fija. El comando anterior elimina los dos últimos caracteres al final de cada línea en el archivo de entrada. Los comandos alternativos son ${line%??}
.
Respuesta2
Suponiendo que las extensiones sean todas de dígitos:
perl -pi -e 's/\.\d+$//' /path/to/file
-i
realiza edición en el lugar (como en sed
). \d
significa dígitos y $
denota el final de la línea.
Con awk
:
awk 'gsub(/\.[0-9]+$/,"")' /path/to/file
gawk
tiene una opción de edición in situ en versiones más nuevas, pero no estoy seguro de qué tan portátil sea. gsub
admite un parámetro opcional que especifica la columna de destino:
awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file
La última forma tiene el efecto secundario no deseado de separar cada columna por un solo espacio en su salida, como si hubiera hecho print $1,..,$NF
. Yo no sé por qué.
Respuesta3
Usarlo awk
es sencillo, simplemente configure su separador de campo como .
:
awk -F. '{print $1}' file
Otro enfoque, usando el shell (en este caso 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
Respuesta4
Esto elimina todo lo que comienza con el punto:
sed 's/\..*//'