una sustituir script reemplazar manejo linea extraer especiales eliminar caracteres caracter cadenas cadena buscar añadir bash shell grep sh gnu-coreutils

bash - sustituir - Extracción de los primeros dos caracteres de una cadena(Shell Scripting)



sed eliminar caracter (12)

Soy nuevo en sed y awk, así que no estoy seguro de cuál es la forma más eficiente de hacerlo.

Estoy buscando extraer las primeras dos letras de una cadena. Podría hacerlo si fueran a ser iguales todo el tiempo, pero parece que no puedo entender cómo decirlo,

Toma n posiciones de esta cuerda de esta cadena más grande x .

ES DECIR.

USCAGoleta9311734.5021-120.1287855805 = US


¿Es esto lo que buscas?

my $string = ''USCAGoleta9311734.5021-120.1287855805''; my $first_two_chars = substr $string, 0, 2;

ref: substr


Has obtenido varias buenas respuestas y yo mismo me encargaría de Bash, pero como preguntaste sobre sed y awk y ( casi ) nadie ofreció soluciones basadas en ellas, te ofrezco estas:

echo "USCAGoleta9311734.5021-120.1287855805" | awk ''{print substr($0,0,2)}''

y

echo "USCAGoleta9311734.5021-120.1287855805" | sed ''s//(^../).*//1/''

El awk debe ser bastante obvio, pero aquí hay una explicación del sed :

  • sustituir "s /"
  • el grupo "()" de dos de los caracteres ".." comenzando al principio de la línea "^" y seguidos por cualquier carácter "." repite cero o más veces "*" (las barras diagonales inversas son necesarias para escapar de algunos de los caracteres especiales)
  • por "/" el contenido del primer grupo (y solo, en este caso) (aquí la barra diagonal inversa es un escape especial que hace referencia a una sub-expresión coincidente)
  • hecho "/"

La forma más fácil es

${string:position:length}

Donde esto extrae la subcadena $length de $string en $position .

Este es un bash incorporado por lo que no se requiere awk o sed.


Muy tarde, de hecho, pero aquí está

sed ''s/.//3g''

O

awk NF=1 FPAT=..

O

perl -pe ''$_=unpack a2''


Probablemente el método más eficiente, si está utilizando el shell bash (y parece que está basado en sus comentarios), es usar la variante de subcadena de expansión de parámetros:

pax> long="USCAGol.blah.blah.blah" pax> short="${long:0:2}" ; echo "${short}" US

Esto se short para ser los primeros dos caracteres de long . Si el long es más corto que dos caracteres, el short será idéntico.

Este método in-shell generalmente es mejor si vas a estar haciendo mucho (como 50,000 veces por informe como mencionas) ya que no hay una sobrecarga de creación de proceso. Todas las soluciones que usan programas externos sufrirán por esa sobrecarga.

Si también deseaba garantizar una longitud mínima , podría rellenarla de antemano con algo como:

pax> long="A" pax> tmpstr="${long}.." pax> short="${tmpstr:0:2}" ; echo "${short}" A.

Esto garantizaría que cualquier elemento de menos de dos caracteres de longitud se rellenara a la derecha con puntos (o algo más, simplemente cambiando el carácter utilizado al crear tmpstr ). No está claro que necesites esto, pero pensé que lo pondría para completarlo.

Una vez dicho esto, hay varias formas de hacerlo con programas externos (como, por ejemplo, si no tiene bash disponible), algunos de los cuales son:

short=$(echo "${long}" | cut -c1-2) short=$(echo "${long}" | head -c2) short=$(echo "${long}" | awk ''{print substr ($0, 0, 2)}'' short=$(echo "${long}" | sed ''s/^/(../).*//1/'')

Los dos primeros ( cut y head ) son idénticos para una cadena de una sola línea; básicamente, ambos simplemente le devuelven los dos primeros caracteres. Se diferencian en que el cut le dará los dos primeros caracteres de cada línea y la head le dará los dos primeros caracteres de la entrada completa

El tercero usa la función awk para extraer los dos primeros caracteres y el cuarto usa grupos de captura sed (usando () y /1 ) para capturar los dos primeros caracteres y reemplazar la línea completa con ellos. Ambos son similares al cut : entregan los dos primeros caracteres de cada línea en la entrada.

Nada de eso importa si está seguro de que su entrada es una sola línea, todos tienen un efecto idéntico.


Si desea usar scripts de shell y no depender de extensiones que no sean posix (como los llamados bashisms), puede usar técnicas que no requieren bifurcar herramientas externas como grep, sed, cut, awk, etc., que luego haz que tu script sea menos eficiente. Tal vez la eficiencia y la portabilidad de posix no es importante en su caso de uso. Pero en caso de que lo sea (o simplemente como un buen hábito), puede usar el siguiente método de opción de expansión de parámetros para extraer los dos primeros caracteres de una variable de shell:

$ sh -c ''var=abcde; echo "${var%${var#??}}"'' ab

Esto usa la expansión del parámetro "prefijo más pequeño" para eliminar los dos primeros caracteres (esta es la parte ${var#??} ), luego la expansión del parámetro "sufijo más pequeño" (la parte ${var% ) para eliminar ese todo-pero- la cadena de los primeros dos caracteres del valor original.

Este método se describió previamente en esta answer a la answer "Shell = Comprobar si la variable comienza con #". Esa respuesta también describe un par de métodos de expansión de parámetros similares que se pueden usar en un contexto ligeramente diferente que el que se aplica a la pregunta original aquí.


Si estás en bash , puedes decir:

bash-3.2$ var=abcd bash-3.2$ echo ${var:0:2} ab

Esto puede ser justo lo que necesitas ...


Si su sistema usa un shell diferente (no bash ), pero su sistema tiene bash , entonces aún puede usar la manipulación inherente de cadenas de bash invocando bash con una variable:

strEcho=''echo ${str:0:2}'' # ''${str:2}'' if you want to skip the first two characters and keep the rest bash -c "str=/"$strFull/";$strEcho;"


Solo grep:

echo ''abcdef'' | grep -Po "^.." # ab


si mystring = USCAGoleta9311734.5021-120.1287855805

print substr(mystring,0,2)

imprimiría en los Estados Unidos

donde 0 es la posición de inicio y 2 es cómo Meny Chars para leer


colrm - eliminar columnas de un archivo

Para dejar los dos primeros caracteres, solo elimine las columnas a partir de 3

cat file | colrm 3


perl -ple ''s/^(..).*/$1/''