Mam ten skrypt
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Działa tylko tyle, że dla pliku o nazwie 001.pngtworzy 001.png.txtzamiast 001.txt.
Jak mogę to zmienić?
Mam ten skrypt
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in $folder/*
do
touch $filePng.txt
done
Działa tylko tyle, że dla pliku o nazwie 001.pngtworzy 001.png.txtzamiast 001.txt.
Jak mogę to zmienić?
Odpowiedzi:
Możesz użyć basenamepolecenia tutaj:
touch "$folder/$(basename "$filePng" .png).txt"
Zwróć uwagę na dodatkowe $folder/. Jest to konieczne, ponieważ polecenie basename usuwa ścieżkę z.
$filePng- one też były przydatne.
$( )ustanawia nowy kontekst cytowania.
Możesz usunąć istniejące rozszerzenie, używając funkcji rozszerzania parametrów powłoki
${parameter%pattern}„Wzór” jest dopasowywany do końca „parametru”. Wynikiem jest rozszerzona wartość „parametru” z usuniętym najkrótszym dopasowaniem.
Więc w twoim przypadku, wymienić $filePng.txtz"${filePng%.png}.txt"
Przy zmianie tego, o czym już wspominał steeldriver - rozszerzanie parametrów - możemy wykonać zamianę łańcucha. Dodatkowo powinieneś cytować zmienne. Poniżej znajduje się edytowany skrypt.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
Jeśli masz dużo plików do utworzenia, warto „dotknąć” więcej niż jednego pliku na raz, aby nie trzeba było przygotowywać nowego procesu dla każdego z nich (co zajmuje sporo czasu, jeśli wykonano wiele tysiąc razy).
xargsTa opcja zapewni wiele ścieżek do touchpolecenia jednocześnie, zwykle kilka tysięcy lub cokolwiek, co system może zmieścić w jednym wierszu polecenia.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
Ta opcja w ogóle nie działa, touchale zamiast tego używa funkcji powłoki Bash / Bourne / POSIX, które w ogóle nie wymagają podprocesów.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done
Jeśli masz pewność, że nie masz plików .pnggdzieś pośrodku nazwy, możesz po prostu użyć tablicy z rozszerzeniem parametrów:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
Zapisuje wszystkie ścieżki do plików kończących się .pngw tablicy, a następnie używa parametru ekspansji stworzyć listę .txtplików, zastępując .pngna .txtna każdej z nich.
Pamiętaj, że to się zepsuje, jeśli masz tak wiele plików, że nie wszystkie mogą zostać przekazane jako argumenty tego samego wywołania touch.
for filePng in "$folder"/*itouch "$filePng".txt- zauważ, że cytujesz je tylko wtedy, gdy poprzedza je znak$.