Tengo varios archivos con el mismo encabezado y diferentes vectores debajo de eso. Necesito concatenarlos a todos, pero solo quiero que se concatene el encabezado del primer archivo y no quiero que se concatenen otros encabezados ya que son todos iguales.
por ejemplo: file1.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E
F
Necesito que la salida sea
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F
¿Podría escribir un script en R pero lo necesito en shell?
grep
(como en la respuesta de sputnik ).head -n 10 file1.txt >output.txt && tail -q -n +11 file*.txt >>output.txt
(si tiene 10 líneas de encabezado). Además, si sus archivos tienen números en sus nombres, tenga cuidado de que esténfile9.txt
ordenados entrefile89.txt
yfile90.txt
. Si los archivos tienen números gustaríafile001.txt
, ...,files009.txt
,files010.txt
, ..., a continuación,files*.txt
aparecerá una lista de ellos en el orden correcto.awk 'FNR==1 && NR!=1{next;}{print}' *.csv
Otra solución, similar a "
cat+grep
" desde arriba, usandotail
yhead
:Escriba el encabezado del primer archivo en la salida:
-
head -2
Obtiene 2 primeras líneas del archivo.Agregue el contenido de todos los archivos:
-
-n +3
hacetail
líneas de impresión desde el 3er hasta el final,-q
le dice que no imprima el encabezado con el nombre del archivo (leerman
),>>
agrega al archivo, no lo sobrescribe como>
.Y seguro que puedes poner ambos comandos en una línea:
o en lugar de
;
poner&&
entre ellos para verificar el éxito.fuente
(head -2 file1.txt ; tail -n +3 -q file*.txt ) > all.txt
o(head -2 file1.txt && tail -n +3 -q file*.txt ) > all.txt
Intenta hacer esto:
NOTA
-v
bandera significa invertir el partido de grep^
en REGEX , significa el comienzo de la cadena:
Es una técnica de corte de matriz bash .
fuente
<header>
líneas en cualquier parte de los archivos, no solo al principio. Esto puede no ser un problema aquí, dependiendo de los datos.grep '^<header>' file1.txt >output.txt && grep -v '^<header>' file*.txt >>output.txt
El
tail
comando (en GNU, al menos) tiene una opción para omitir un número dado de líneas iniciales. Para imprimir desde la segunda línea en adelante, es decir, omitir un encabezado de una línea, haga lo siguiente:tail -n+2 myfile
Entonces, para mantener el encabezado de dos líneas del primer archivo pero no el segundo, en Bash:
O, para muchos archivos:
Si se sabe que cierta cadena está presente en todas las líneas de encabezado pero nunca en el resto de los archivos de entrada,
grep -v
es un enfoque más simple, como lo demostró sputnik.fuente
Más corto (no necesariamente más rápido) con
sed
:Esto eliminará todas las líneas que comiencen a
<header>...
partir de la línea 3, por lo que se conserva el primer encabezado y se eliminan los otros encabezados. Si hay un número diferente de líneas en el encabezado, ajuste el comando en consecuencia (por ejemplo, para el uso del encabezado de 6 líneas en7
lugar de3
).Si se desconoce el número de líneas en el encabezado, puede intentar de esta manera:
fuente
Suponiendo que está utilizando una carpeta con archivos .txt con el mismo encabezado que debe combinarse / concatenarse, este código combinaría todos los archivos txt en all.txt con un solo encabezado. la primera línea (líneas separadas por punto y coma) reúne todos los archivos de texto para concatenar, la segunda línea genera el encabezado del primer archivo txt en all.txt , y la última línea concatena todos los archivos de texto reunidos sin el encabezado (iniciando el concatenación desde la fila 2 en adelante) y lo agrega a all.txt .
fuente