Cadenas de prefijo y sufijo para cada línea de salida desde el comando


17

Me he encontrado con un problema al intentar escribir un script Bash. Cuando grepsale, devuelve (generalmente) muchas líneas. Me gustaría agregar un prefijo y un sufijo a cada una de estas líneas de salida.

También me gustaría señalar que estoy lsentrando grep, como:

ls | grep

2
No deberías analizar ls, es un mal juju. Además, ¿tiene que ser grep? ¿Y puedes dar algún ejemplo de salida?
Sobrique

1
¿Qué desea que haga su secuencia de comandos si el nombre de archivo contiene una nueva línea?
Tai Viinikka

Respuestas:


27

Con sed:

ls | grep txt | sed 's/.*/prefix&suffix/'

3
O, sedsiendo un superconjunto de grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'ols | sed -n 's/.*txt.*/prefix&suffix/p'
Stéphane Chazelas

@ StéphaneChazelas: Gracias por esta pista.
Cyrus

5

Con sed:

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

Pero tenga en cuenta que esto tiene problemas con los nombres de archivo con saltos de línea y todos los problemas variados de análisis lsque generalmente es una mala idea.

Con perl

perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

Nota: Perl greppuede tomar un patrón, como el grepcomando, pero también puede hacer cosas como aplicar pruebas de archivo.

P.ej

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

Dentro grepdel iterador predeterminado $_se establece el valor del elemento actual, por lo que puede aplicar sed/ grepregex estilo, o realizar una variedad de tareas basadas en $_.


¿Cómo incluiría una variable como sufijo / prefijo en su primer ejemplo usando ´sed´?
SpecialBomb

Cambie las comillas y simplemente use em.
Sobrique

2

En este caso, GNU le findpermite hacer todas estas cosas de una vez, eliminando tuberías y el análisis potencialmente problemático de ls:

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

findno es una buena forma de modificar arbitrariamente la salida de otros comandos, por supuesto!)

Algunas notas:

  • -maxdepth 1y -name [^.]*hacer que la coincidencia de nombres funcione igual que un simple ls(o ls .). Puede usar cualquier globo de estilo shell, pero tenga en cuenta que "*" coincidirá con un "." en un nombre diferente bash, [^.]*significa cualquier cosa que no tenga un "."
  • MYPATTERN es un ERE POSIX adecuado (el tipo predeterminado es Emacs, consulte aquí ), pero debe coincidir con el nombre de archivo completo, así que use algo como en .*thing.*lugar de solothing
  • probablemente pueda usar uno de -name/ en -regexlugar de ambos (por ejemplo, -regex "[^.]. MYPATTERN " .
  • -printfadmite muchas cosas , %nes el archivo sin nombre o el nombre del directorio

(esto puede depender de su versión de find, sin embargo, consulte la sección "CONFORMIDAD DE NORMAS" de su página de manual)

Como una alternativa posible sin necesidad de programas externos, bashtiene compgenque, entre otras cosas, expande globos, equivalente a un lssin opciones:

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

Esto maneja los nombres de archivo con espacios en blanco, incluidas las nuevas líneas. compgen -G "*"debería proporcionar el mismo resultado que un plano ls(pero tenga en cuenta que ls *es algo completamente diferente). Aún lo necesitará grep, y esto puede o no resolver el problema, pero vale la pena mencionarlo.


0

sedy las findsoluciones son cuestionadas si su prefijo / sufijo incluye caracteres clave regex o si desea pasar una variable de entorno (en lugar de un valor inmediato), xargs+ echopodría ser más apropiado aquí.

Con variable de entorno:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

Con una línea:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.