Переименование файлов дает странный результат в tcsh

#!/usr/bin/tcsh setenv LC_ALL de_DE rm /home/users0/me/master/me/LookupScripts/Sampa/* foreach f ( /home/users0/me/master/me/LookupScripts/Tokenized/*.txt ) set g = "`basename $f .txt`" set h = "`echo $g | tr "tokenized" "sampa"`" cat $f | ./a4.lookup > Sampa/$h.txt end 

В /home/users0/me/master/me/LookupScripts/Tokenized/ меня есть некоторые .txt файлы, которые называются randomnumber_tokenized.txt . Я хочу запустить сценарий на них, и я хочу поместить вывод сценария в папку Sampa/ и я хочу сохранить randombumber_ в именах файлов, но я хочу переименовать tokenized часть в sampa , чтобы новые файлы выглядели например randomnumber_sampa.txt .

Странно, хотя в конце файлы не называются randomnumber_sampa.txt но randomnumber_samaaaaaa.txt

Я подозреваю, что это либо проблема с tcsh, либо из-за команды setenv .

Что я делаю не так?

Ваша непосредственная проблема в том, что tr не делает то, что вы думаете. tr выполняет замену символа , а не замену строки. Команда tr "tokenized" "sampa" заменяет t на s , o на a , k на m , ( e на p переопределяется последующим вхождением e ) и n , i , z , e и d на a .

Чтобы выполнить замену строки, вы можете использовать sed. Но это несколько неудобно, и трудно понять. Для простых манипуляций с строками используйте строковые манипуляции оболочки вместо внешних инструментов.

В Tcsh отсутствуют строковые манипуляционные конструкции. Но (t) csh не был оболочкой командной строки уровня 1 за последние 20 лет или около того и никогда не был хорош для сценариев . Просто не пишите скрипты csh.

Также:

  • Никогда не устанавливайте LC_ALL для чего-либо другого, кроме C (или его синонима POSIX ). LC_ALL переопределяет все категории, и это может вызвать проблемы. Чтобы установить значение по умолчанию для всех категорий, используйте LANG . Но в сценариях C обычно требуется вам, за исключением LC_CTYPE (набор символов) и LC_MESSAGES (сообщения для пользователя).
  • Строковое манипулирование в sh выполняется через расширение параметра .
  • Plain sh не имеет строковой конструкции замены, но bash делает.
  • Всегда используйте двойные кавычки вокруг переменных подстановок
 #!/bin/bash export LC_ALL=C for f in /home/users0/me/master/me/LookupScripts/Tokenized/*.txt; do g="${f##*/}" h="${g//tokenized/sampa}" ./a4.lookup <"$f" >"Sampa/$h.txt" end на #!/bin/bash export LC_ALL=C for f in /home/users0/me/master/me/LookupScripts/Tokenized/*.txt; do g="${f##*/}" h="${g//tokenized/sampa}" ./a4.lookup <"$f" >"Sampa/$h.txt" end