¿Cómo puede encontrar un patrón en un campo pero agregar otro (misma fila)?

2

Tengo un archivo de texto que tiene valores separados por comas. El campo 1 tiene un campo que debe coincidir, pero el campo dos necesita una sustitución basada en la coincidencia.

Ejemplo:

A, C
B, C

Resultado:
A, D
B, C

Supongo que el comando se vería más o menos así:

sed 's/A/D/'

Gracias

sgp667
fuente
¿Qué pasó cuando lo probaste?
Glenn Jackman
@glennjackman amigo, si intentas 's / A / D /' obviamente no hace lo que quiere. Sabe que solo pensó que la solución se basaría en esa idea general. Y tiene razón ... yo diría que en lugar de reemplazar A con D, es reemplazar A, bla con A, bleh. así que combine la primera parte y mencione ambas partes en el reemplazo, dejando la primera parte como está y haciendo que la segunda parte sea diferente.
barlop

Respuestas:

0

Qué tal esto

$ echo A,fgfdgd|sed -r 's/A,[^,]*/A,D/'
A,D

Si la primera columna es A, y luego hay una coma, y ​​hay algo en la segunda columna, reemplaza el lote con A, D. Esto solo sucederá cuando coincida con A en la primera columna (seguido de una coma y lo que sea en la segunda columna).

Un ejemplo con un archivo

Esto convierte tu ejemplo en tu resultado. Entonces, donde su primera columna es A, su segunda columna se convierte en D.

$ cat a.b
A,C
B,C


$ sed -r 's/A,[^,]*/A,D/' a.b
A,D
B,C


$
barlop
fuente
1

Use una expresión de dirección para seleccionar las líneas que desea editar, luego use un reemplazo regular para hacer el reemplazo. Una cosa divertida de sed es que, antes del comando "s", puede especificar un número de línea o una expresión regular para elegir las líneas que le interesan (la dirección también puede ser un inicio y un final separados por comas que especifiquen todas las líneas contenida dentro del "rango de direcciones", pero dejando la segunda parte seleccionada selecciona líneas individuales).

En su expresión de dirección, busque "no una coma, seguida de lo que desea".

En el reemplazo, recuerde las cosas antes de su patrón, luego coloque las partes "antes" antes de su cadena de reemplazo. Recuerdas la parte de "antes" porque quieres que las cosas de antes solo incluyan una coma, ni más ni menos. Aquí muestra que coincide con el primer campo y solo impacta el segundo; Estoy reemplazando "la" con "moo" en la segunda columna de líneas que coinciden con "atter" en la primera columna.

$ echo -e "pattern,blah,aaa\npattern,bleh,stuff" | sed '/[^,]*atter/s/\(^[^,]*,[^,]*\)la/\1moo/g'
pattern,bmooh,aaa
pattern,bleh,stuff

Esto por sí solo no funcionará correctamente con comas escapadas en los campos, por lo que esperamos que su archivo CSV sea simple. :)

dannysauer
fuente
usted dice en su primera línea "Use una expresión de rango" pero ¿lo hizo? Creo que una expresión de rango son dos direcciones separadas por una coma. una dirección puede tomar la forma de una expresión regular, pero para que sea un rango, creo que tiene que ser dos direcciones como '/ regexp /, / regexp / s / a / b'
barlop
Es un "rango de direcciones" expresado en forma de una sola dirección, que podría decirse que es un rango corto muy corto. Usé una terminología poco clara, y olvidé volver y arreglarlo después de que me di cuenta. :) Está editado ahora.
dannysauer
mirando en el manual de sed, el término "expresión de dirección" (que utilizó en su última edición) no existe. hay una dirección y un rango de direcciones. usó una dirección, aunque como dice en su edición, se puede usar un 'rango de direcciones'. En su comentario, escribe "Es un" rango de direcciones "expresado en forma de una sola dirección" No creo que sea la terminología correcta. Mirando el manual, no veo que esa dirección se llame rango. Un rango debe ser dos direcciones.
barlop
La frase "expresión de dirección" se refiere a una dirección definida por una expresión regular. Intenta correr sed '/barlow'y mira el mensaje de error; dice "address regexp", que es la abreviatura de "address regular expression".
dannysauer
Con respecto a un rango, en la documentación de sed una dirección única se denomina "singleton". Un "singleton" es un conjunto con un elemento. Por lo tanto, la dirección es una tupla con una cardinalidad de 0, 1 o 2. Un rango no necesita ser dos direcciones diferentes ( sed -n '1,1'p behaves the same as sed -n '1p' '), por lo que parece razonable considerar el caso singleton como abreviatura sintáctica para un rango donde los puntos de inicio y finalización son idénticos. Así es como lo implementa match_address_p en la fuente.
dannysauer