Suponiendo que desea buscar todos los archivos .zip
en o debajo del directorio actual y verificar si hay algo con el mismo nombre pero sin el sufijo de nombre de archivo .zip
:
find. -type f -iname '*.zip' -exec sh -c '
for a do
n="${a%.zip}"
[ -e "$n" ] && printf "%s\n" "$n"
done' sh {} +
Con un directorio que contiene
file
file.zip
file2.zip
file3
file3.zip
el comando anterior generaría
./file
./file3
Esto se hace buscando todos los archivos .zip
y, para todos los archivos encontrados, ejecute un breve script de shell que elimine la extensión de cada nombre y verifique si ese nuevo nombre existe o no.
Alternativamente, un poco más corto,
find. -iname '*.zip' -exec sh -c '[ -e "${0%.zip}" ]' {} ';' -print
Esto también usa un script de shell de ayuda, pero solo está probando la existencia del nombre de archivo sin el sufijo .zip
. Si existe un sufijo -menos nombre, se genera la ruta del archivo zip.
También posiblemente relevante:
Как намекает Подстановочный знак , скриптовый редактор упрощает эту задачу. Чтобы заменить строки с третьей по шестую после шаблона bb/bb/bb/bb
одной строкой line uu/uu/uu/uu
, вы можете использовать следующий конвейер ed
:
printf '%s\n' '/bb\/bb\/bb\/bb' '+3,+6c' 'line uu/uu/uu/uu' '.' 'wq' | ed -s file.txt > /dev/null
На высоком уровне мы отправляем разделенные новой строкой -команды через конвейер в ed
, из которых мы указываем молча редактировать файл с именем file.txt
и перебрасывать любой «стандартный вывод» в долото -ковш /dev/null
. Флаг -s
подавляет нормальный вывод из ed
числа прочитанных и записанных байтов. ed
также будет печатать совпадающие строки ("bb" в этом сценарии ), так что они отбрасываются через > /dev/null
. Мы могли бы сбросить флаг -s
и перенаправить как stdout, так и stderr.
Сами команды ed
являются:
/bb\/bb\/bb\/bb
--найдите строку, содержащую /bb/bb/bb/bb
, где мы должны экранировать косую черту, потому что в противном случае ed
думает, что мы пытаемся отправить странную bb/bb/bb
команду на строку, соответствующую /bb/
, из-за forard -косая черта — ситнатический символ. +3,+6c
--с этой строки, c
вывесить строки с 3-й по 6-ю после нее... line uu/uu/uu/uu
--на эту строку .
--и скажите ed
, что мы закончили замену строк wq
--затем w
записать файл на диск и q
uited
Обратите внимание, что это предполагает наличие bb/bb/bb/bb
в файле; в противном случае вы получите ошибку, когда попытаетесь указать ed
отредактировать строки с третьей по шестую после конца файла. Если вы не можете гарантировать, что шаблон существует в файле, вы можете поставить перед этим сценарием grep -q bb/bb/bb/bb file.txt && printf...
для условного выполнения конвейера.
С ГНУsed
:
sed -ne '\#bb/bb/bb/bb#{p;n;p;n;p;n;n;n;n;a line uu/uu/uu/uu' -e ';b };p' file.txt
Выход:
line aa/aa/aa/aa
line bb/bb/bb/bb
line cc/cc/cc/cc
line dd/dd/dd/dd
line uu/uu/uu/uu
line ii/ii/ii/ii
Чтобы сохранить вывод в файл.txt , измените -ne
на -ine
.
Обратите внимание, :пробел в коде с двумя переключателями -e
связан с тем, что пробел указывает командеa
ppend , где остановить добавление.
Другой метод заключается в использовании POSIX sed
, но это не -однострочный вкладыш:
sed -n '\#bb/bb/bb/bb#{p;n;p;n;p;n;n;n;n;a\
line uu/uu/uu/uu
b };p' file.txt
В POSIX sed
вы можете сделать следующее:
$ sed -e '
\:line bb/bb/bb/bb:!b
n;n;n
N;N;N
s:.*:line uu/uu/uu/uu:
' inp
После того, как мы напечатали целевую строку и две строки после нее, мы накапливаем следующие три строки в пространстве шаблонов и заменяем все пространство шаблонов намеченной строкой. О переводе строки заботится сам sed при переносе пространства шаблона в стандартный вывод.
Обратите внимание, что мы предполагаем, что после целевой строки достаточно строк, чтобы N
не завершился ошибкой.