Dobrym nawykiem jest cytowanie zmiennych. Skrypt powłoki to dziwny język, który ewoluował z czasem, a nie był doskonale zaprojektowany od samego początku, więc niestety konieczne są pewne irytujące rzeczy. Bez cytowania zmiennych, białe znaki lub gwiazdki w treści zmiennych spowodują, że rzeczy się psują. Aby skrypty były bardziej niezawodne, zawsze otaczaj użycie zmiennych podwójnymi cudzysłowami. Tutaj powiedziałbyś for filePng in "$folder"/*i touch "$filePng".txt - zauważ, że cytujesz je tylko wtedy, gdy poprzedza je znak $.
Muzer
3
Wygląda to na problem XY… Dlaczego próbujesz to zrobić?
JeromeJ
Odpowiedzi:
16
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.
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.
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).
Opcja 1: podstawienie wzoru + xargs
Ta 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.
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$
.Odpowiedzi:
Możesz użyć
basename
polecenia tutaj:Zwróć uwagę na dodatkowe
$folder/
. Jest to konieczne, ponieważ polecenie basename usuwa ścieżkę z.źródło
$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
Więc w twoim przypadku, wymienić
$filePng.txt
z"${filePng%.png}.txt"
źródło
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.
źródło
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).
Opcja 1: podstawienie wzoru +
xargs
Ta opcja zapewni wiele ścieżek do
touch
polecenia jednocześnie, zwykle kilka tysięcy lub cokolwiek, co system może zmieścić w jednym wierszu polecenia.Opcja 2: rozszerzenie parametrów + przekierowanie wyjścia polecenia
Ta opcja w ogóle nie działa,
touch
ale zamiast tego używa funkcji powłoki Bash / Bourne / POSIX, które w ogóle nie wymagają podprocesów.źródło
Jeśli masz pewność, że nie masz plików
.png
gdzieś pośrodku nazwy, możesz po prostu użyć tablicy z rozszerzeniem parametrów:Zapisuje wszystkie ścieżki do plików kończących się
.png
w tablicy, a następnie używa parametru ekspansji stworzyć listę.txt
plików, zastępując.png
na.txt
na 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
.źródło