Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

198
Views
¿Cómo puedo mostrar palabras únicas contenidas en una cadena Bash?

Tengo una cadena que tiene palabras duplicadas. Me gustaría mostrar solo las palabras únicas. la cadena es:

 variable="alpha bravo charlie alpha delta echo charlie"

Conozco varias herramientas que pueden hacer esto juntas. Esto es lo que descubrí:

 echo $variable | tr " " "\n" | sort -u | tr "\n" " "

¿Cuál es una forma más efectiva de hacer esto?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Usar una expansión de sustitución de Bash

La siguiente expansión de parámetros de shell sustituirá los espacios por líneas nuevas y luego pasará los resultados a la utilidad de ordenación para devolver solo las palabras únicas.

 $ echo -e "${variable// /\\n}" | sort -u alpha bravo charlie delta echo

Esto tiene el efecto secundario de clasificar sus palabras, ya que las utilidades sort y uniq requieren que se clasifique la entrada para detectar duplicados. Si eso no es lo que desea, también publiqué una solución de Ruby que conserva el orden original de las palabras.

Palabras de reincorporación

Si, como señaló un comentarista, está tratando de volver a ensamblar sus palabras únicas en una sola línea, puede usar la sustitución de comandos para hacer esto. Por ejemplo:

 $ echo $(echo -e "${variable// /\\n}" | sort -u) alpha bravo charlie delta echo

La falta de comillas en torno a la sustitución del comando es intencional. Si lo cita, las líneas nuevas se conservarán porque Bash no dividirá las palabras . Sin comillas, el shell devolverá los resultados como una sola línea, por poco intuitivo que parezca.

over 4 years ago · Santiago Trujillo Report

0

Puede usar xargs :

 echo "$variable" | xargs -n 1 | sort -u | xargs
over 4 years ago · Santiago Trujillo Report

0

Nota: esta solución asume que todas las palabras únicas deben generarse en el orden en que se encuentran en la entrada . Por el contrario, el intento de solución del propio OP genera una lista ordenada de palabras únicas.

Una solución simple solo de Awk (compatible con POSIX) que es eficiente al evitar una canalización (que invariablemente involucra subcapas).

 awk -v RS=' ' '{ if (!seen[$1]++) { printf "%s%s",sep,$1; sep=" " } }' <<<"$variable" # The above prints without a trailing \n, as in the OP's own solution. # To add a trailing newline, append `END { print }` to the end # of the Awk script.
  • Tenga en cuenta cómo $variable está entre comillas dobles para evitar que se produzcan expansiones de shell accidentales, en particular la expansión del nombre de la ruta (globbing), y cómo se proporciona a Awk a través de una cadena aquí ( <<< ).

  • -v RS=' ' le dice a Awk que divida la entrada en registros por un solo espacio.

    • Tenga en cuenta que la última palabra incluirá el salto de línea final de la línea de entrada, por lo que no usamos $0 , el registro completo, sino $1 , el primer campo del registro, que tiene el salto de línea eliminado debido al comportamiento predeterminado de división de campos de Awk.
  • seen[$1]++ es un modismo común de Awk que crea una entrada para $1 , la palabra de entrada, en una matriz asociativa seen , si aún no existe, o incrementa su recuento de ocurrencias.

  • !seen[$0]++ por lo tanto, solo devuelve verdadero para la primera aparición de una palabra dada (donde seen[$0] es implícitamente cero/la cadena vacía; el ++ es un incremento posterior y, por lo tanto, no tiene efecto hasta después de evaluar la condición)

  • {printf "%s%s",sep,$1; sep=" "} imprime la palabra en cuestión $1 , precedida por el separador sep , que es implícitamente la cadena vacía para la primera palabra, pero un solo espacio para las palabras posteriores, debido a que se establece sep en " " inmediatamente después.


Aquí hay una variante más flexible que maneja cualquier espacio en blanco entre las palabras de entrada ; funciona con GNU Awk y Mawk [1] :

 awk -v RS='[[:space:]]+' '{if (!seen[$0]++){printf "%s%s",sep,$0; sep=" "}}' <<<"$variable"
  • -v RS='[[:space:]]s+' le dice a Awk que divida la entrada en registros por cualquier combinación de espacios, tabulaciones y saltos de línea.

[1] Desafortunadamente, BSD/OSX Awk (en estricto cumplimiento con la especificación POSIX ), no admite el uso de expresiones regulares o incluso literales de varios caracteres como RS , el separador de registro de entrada.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!