У мене є цей сценарій
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Працює саме так, для файлу з іменем 001.pngвін створюється 001.png.txtзамість 001.txt.
Як я можу це змінити?
У мене є цей сценарій
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Працює саме так, для файлу з іменем 001.pngвін створюється 001.png.txtзамість 001.txt.
Як я можу це змінити?
Відповіді:
Ви можете використовувати basenameкоманду тут:
touch "$folder/$(basename "$filePng" .png).txt"
Зверніть увагу на додаткове $folder/. Це необхідно, оскільки команда basename видаляє шлях з.
$filePng- вони теж були корисними.
$( )встановлює новий контекст цитування.
Ви можете видалити існуюче розширення за допомогою функцій розширення параметрів оболонки
${parameter%pattern}"Шаблон" узгоджується з кінцем "параметра". Результатом є розширене значення 'параметра' із видаленим найкоротшим збігом.
Тож у вашому випадку замініть $filePng.txtна"${filePng%.png}.txt"
З урахуванням варіанту того, що вже згадувався steeldriver - розширення параметрів, - ми можемо використовувати заміну рядків для виконання цієї роботи. Крім того, слід навести змінні. Нижче ваш відредагований сценарій.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
Якщо у вас є багато файлів для створення, варто було б "торкнутися" декілька файлів одночасно, так що вам не потрібно роздрібнювати новий процес для кожного з них (що займає досить багато часу, якщо виконується кілька тис. разів).
xargsЦей параметр надасть touchкоманді декілька шляхів одночасно, як правило, кілька тисяч або все, що система може вмістити в одному командному рядку.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
Ця опція взагалі не працює, touchале використовує функції оболонки Bash / Bourne / POSIX, які взагалі не потребують підпроцесів.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done
Якщо ви впевнені, що у вас немає файлів з .pngдесь посеред імені, ви можете просто використовувати масив з розширенням параметра:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
Тут зберігаються всі шляхи до файлів, що закінчуються в .pngмасиві, а потім використовується розширення параметрів для створення списку .txtфайлів, замінюючи .pngдля .txtкожного з них.
Майте на увазі, що це порушиться, якщо у вас так багато файлів, що їх не можна передавати як аргументи на одне виклик touch.
for filePng in "$folder"/*іtouch "$filePng".txt- зауважте, ви цитуєте їх лише тоді, коли перейдете до а$.