Ответ Жиля верен в том, что версия команды find
для Windows предшествует версии cygwin, и поэтому она вызывается.
Однако использование Cygwin будет означать, что любые командные файлы, использующие команду windows find
, теперь фактически будут вызывать команду cygwin find
, что может быть не тем, что вам нужно.
На мой взгляд, наиболее симбиотическим способом работы обоих является выполнение следующих действий:
find
и переименуйте / скопируйте ее в
lfind.exe
(или любое другое имя, не указанное в PATH Windows) ~ / .bashrc
добавьте строку alias find = lfind
Таким образом , когда вы запускаете find
из терминала cygwin, вы будете использовать версию cygwin, но командные файлы будут использовать версию Windows.
Примечание: вам все равно понадобится каталог bin cygwin в вашем PATH, но теперь он может быть дальше от системного каталога Windows.
Leyendo nuevamente su descripción, entiendo que desea la primera coincidencia del patrón B de abajo hacia arriba hasta (subiendo )la primera coincidencia del patrón A. Pero las secciones resultantes deben estar en el orden en que el archivo posee.
Eso requiere mucha lógica. El siguiente script shell lo hace todo. Colocará los resultados en el orden interno correcto en los archivos E
y algún número, el primer archivo(E1
)tendrá la primera coincidencia desde arriba, el último archivo tendrá la sección de la última coincidencia.
#!/bin/bash
rm -rf resE* E*
tac../example_file.txt |
awk 'BEGIN{i=1}
/^AK5\*R.*/{p=1}
{if(p==1){f="resE" i;print($0)>>f;close(f)}}
/^AK2.*/{if(p==1){i++};p=0}
'
set -- resE*
c=$#
for (( i=1;i<=$c;i++)); do
pos=$(($c-$i+1))
[ -f "$1" ] && tac "$1" > "E$pos"
shift
done
Los rangos resultantes serán:
$ cat E1
AK2*777*7777777
AK3*S6*5**3
AK3*A2*5**3
AK4*3*6969*4
AK4*7*6969*4
AK5*R*5
$ cat E2
AK2*777*7777777
AK3*J7*5**3
AK4*3*6969*4
AK5*R*5
ex
al rescate otra vez! ex
es el editor de archivos programable especificado por POSIX -. Para cualquier cosa que implique direccionamiento hacia atrás, suele ser una solución mucho mejor que Awk o Sed.
El siguiente delineador -funciona perfectamente en tuexample_file2.txt
:
printf '%s\n' 'g/AK5[*]R/?AK2?,.p' | ex example_file.txt
En su example_file.txt
, también funciona, pero debido a que el comando lobal g
en ex
no puede escribir en un destino separado para cada rango sobre el que se actúa, los dos archivos de salida deseados se fusionan así:
AK2*777*7777777
AK3*S6*5**3
AK3*A2*5**3
AK4*3*6969*4
AK4*7*6969*4
AK5*R*5
AK2*777*69696969
AK3*J7*5**3
AK4*3*6969*4
AK5*R*5
Sin embargo, esto es bastante fácil de manejar con otra herramienta POSIX, csplit
, que está diseñada para dividir archivos según un "contexto".
patA='AK5[*]R'
patB='AK2'
printf '%s\n' "g/$patA/?$patB?,.p" |
ex example_file.txt |
csplit -f my_unique_prefix_ -n 1 -s -k - "/$patB/" '{999}'
for f in my_unique_prefix_*; do
mv "$f" "e${f##my_unique_prefix_}.txt";
done
rm e0.txt
Hay un elemento final para que esta sea una solución perfecta, que es volver a numerar los archivos en orden inverso. No he hecho esta parte.
Si no le importa que la numeración de los archivos esté en el mismo orden que el archivo, y si no le importa si se omite la extensión .txt
, y si no le importa si los archivos están numerados desde e01
en lugar de desde e1
, y si no le importa que se imprima un mensaje de diagnóstico sobre cuántas líneas se colocaron en cada archivo, entonces podemos simplificar:
patA='AK5[*]R'
patB='AK2'
printf '%s\n' "g/$patA/?$patB?,.p" |
ex example_file.txt |
csplit -f e -k - "/$patB/" '{999}'
rm e00