Estoy tratando de extraer un campo específico en una línea específica de un archivo CSV.
Puedo hacerlo de acuerdo con la fila de números, pero a veces el número de fila del archivo cambia, por lo que esto no es tan flexible.
Quería intentar hacerlo para extraer un nombre específico antes del campo que me interesa.
[Header] File,5 Researcher Name,Joe Black Experiment,Illumina-Project Date,05/02/2021 Pipeline,RNA_PipelineEn este caso, quiero extraer el investigador y el nombre del experimento del archivo CSV:
Proyecto Joe Black Illumina
Lo siguiente funciona, pero como dije, no es tan flexible:
awk -F',' 'NR == 3 { print $2 }' test.csvAsí que estaba tratando de hacer algo como lo que encontré, pero no he tenido éxito.
awk -F',' 'Line == "Researcher Name" { print $1 }' test.csvPuedes probar esto
$ awk -F"," '/Name/{name=$2} /Experiment/{print name, $2}' file Joe Black Illumina-Project /Name/{name=$2} : haga coincidir el nombre o, más específicamente, $1=="Researcher Name" , cree un name de variable y almacene el contenido de la columna 2 $2
/Experiment/{print name, $2}' - Experimento de coincidencia, variable de name de impresión y $2
Si desea imprimir la segunda columna de la línea siguiente después de hacer coincidir Researcher Name , primero puede verificar si el primer campo coincide con el Nombre del investigador.
Si es así, agregue el segundo campo a una variable, por ejemplo, str y procese la siguiente línea.
En la siguiente línea (si la variable no es 0 o una cadena vacía) puede concatenar el segundo campo de esa línea, volviendo a establecer la variable en una cadena vacía.
awk -F',' '$1 ~/Researcher Name/ { str=$2; next } { if(str){ print str, $2 str="" } }' fileProducción
Joe Black Illumina-ProjectUtilice este Perl de una sola línea:
perl -0777 -lne '( $researcher_name ) = /Researcher Name,([^,\n]*)/; ( $experiment ) = /Experiment,([^,\n]*)/; print "$researcher_name $experiment\n";' test.csv El one-liner de Perl utiliza estos indicadores de línea de comando:
-e : Le dice a Perl que busque el código en línea, en lugar de en un archivo.
-n : Recorre la entrada una línea a la vez, asignándola a $_ por defecto.
-l : elimine el separador de línea de entrada ( "\n" en *NIX de forma predeterminada) antes de ejecutar el código en línea y agréguelo al imprimir.
-0777 : Slurp archivos enteros.
([^,\n]*) : captura en y devuelve el patrón entre paréntesis (...) . El patrón es cualquier carácter excepto coma y salto de línea, repetido 0 o más veces (el modificador * ).
VER TAMBIÉN:
perldoc perlrun : cómo ejecutar el intérprete de Perl: interruptores de línea de comandos
perldoc perlre : Expresiones regulares de Perl (regex)
perldoc perlre : expresiones regulares de Perl (regexes): cuantificadores; clases de personajes y otros escapes especiales; afirmaciones; Grupos de captura
perldoc perlrequick : inicio rápido de expresiones regulares de Perl
Siempre que sus datos de entrada contengan pares de nombre-valor, es mejor crear primero una matriz que contenga esas asignaciones ( f[] a continuación) y luego puede imprimir/probar/modificar los valores que desee en el orden que desee simplemente indexando la matriz por los nombres.
Mira lo fácil que es hacer lo que quieras con este enfoque:
$ awk -F, '{f[$1]=$2} END{print f["Researcher Name"], f["Experiment"]}' file Joe Black Illumina-Projectpero también lo fácil que es hacer cualquier otra cosa que pueda necesitar en el futuro, por ejemplo:
$ awk -F, ' { f[$1]=$2 } END { if ( (f["File"] > 3) && (f["Date"] ~ /2021/) ) { print f["Experiment"], f["Pipeline"], f["Researcher Name"] } } ' file Illumina-Project RNA_Pipeline Joe BlackCon las muestras mostradas, intente seguir el código awk , escrito y probado en GNU awk . La explicación simple sería establecer RS como \nFecha y establecer separadores de campo como Researcher Name, O \nExperiment, luego imprimir el segundo y tercer campo según la salida requerida de OP.
awk -v RS='\nDate' -F'Researcher Name,|\nExperiment,' 'FNR==1{print $2,$3;exit}' Input_file