Как пропустить подкаталоги в цикле for на основе одного только имени?

Второе node-dev не исполняемый файл, и символьная ссылка указывает на это. Хотя символьная ссылка является исполняемым файлом (символьные ссылки всегда 777), это - режим файла, это указывает на это на количества; отметьте тот вызов chmod на ссылке на самом деле изменяет режим файла, на который это указывает на (полномочия символьной ссылки никогда не изменяются).

Таким образом, возможно, необходимо добавить исполняемый бит для всех:

chmod 755 /home/nodejs/spicoli-authorization/node_modules/.bin/node-dev
2
04.10.2015, 18:53
4 ответа

Если имена ваших каталогов такие простые, как вы показываете (по крайней мере, если они не содержат пробелов или других странностей), вы можете просто сделать:

for d in $(ls | sort -r | rev | uniq -s1 | rev); do echo "$d"; done

Измените echo "$ 4d" на то, что должен делать ваш цикл. Однако это не удастся, если имена ваших каталогов не совсем такие, как вы их показываете, поскольку он уязвим для всех ошибок синтаксического анализа ls. Он работает, сначала перечисляя каталоги, сортируя их в обратном порядке, меняя их местами (так a1 становится 1a ), сохраняя только уникальные строки, но игнорируя 1-й символ ( uniq - s1 ) и перевернув их, чтобы вернуть исходное имя.

0
27.01.2020, 21:59

У меня есть несколько сложный небольшой конвейер для выполнения вашей работы:

#!/bin/bash
find . -maxdepth 1 -type d |
sed -e '/\.$/d' -e '/\.\.$/d' -e 's/\.\/\(.\)\(.\)/\1   \2/' |
sort -k1.1 -k2.1n |
awk 'BEGIN {last=""}
        {
                if (last == "") {
                        last = $1; number = $2
                } else if ($1 != last) {
                        printf "%s%s\n", last, number;
                        last = $1; number = $2
                } else {
                        number = $2
                }
        }
        END { printf "%s%s\n", last, number }
'

Вам, вероятно, придется изменить аргументы на найти , чтобы получить именно то, что вы хотите.

1
27.01.2020, 21:59

Один из способов действовать по последнему элементу серии - перебрать все элементы, запоминая предыдущий элемент. Если вы обнаружите, что начинается новая серия, действуйте по запомненному предыдущему элементу. Непроверенный код. Я предполагаю, что вас интересуют только каталоги, первый символ которых не точка, а последний - цифра.

act_on () {
  …
}
previous_prefix=0
previous_name=
for x in *[0-9]/; do
  x=${x%/}
  digits=${x##*[!0-9]}
  prefix=${x%"$digits"}
  if [ "$prefix" != "$previous_prefix" ] && [ "$previous_prefix" != "0" ]; then
    # New prefix, so act on the previous element
    act_on "$previous_name"
  fi
  previous_prefix=$prefix
  previous_name=$x
done
act_on "$previous_name"

Имейте в виду, что foo9 сортируется после foo10. В zsh используйте *[0-9](/on), чтобы использовать числовую сортировку, где 9 сортируется перед 10. Если вы не используете zsh, потребуется другой подход. Один из способов - действовать только с первым элементом серии, но вместо того, чтобы действовать с найденным элементом, использовать его префикс и определить последний элемент числового ряда.

act_on () {
  …
}
previous_prefix=0
previous_name=
for x in *[0-9]/; do
  x=${x%/}
  digits=${x##*[!0-9]}
  prefix=${x%"$digits"}
  if [ "$prefix" != "$previous_prefix" ]; then
    suffixes=
    for y in "$prefix"*; do
      suffixes="$suffixes
${y#"$prefix"}"
    done
    last_suffix=$(echo "$suffixes" | sort -n | tail -n 1)
    act_on "$prefix$last_suffix"
  fi
  previous_prefix=$prefix
  previous_name=$x
done
1
27.01.2020, 21:59

Это похоже на достижение вашей цели

#!/bin/bash
for DIR in {a..z}
do
 GOOD=$(find ${DIR}[0-9] -type d -print -prune 2>/dev/null | tail -1)
 if [[ "$GOOD" ]]; then
  echo $GOOD
 fi
done

Пример использования:

$ mkdir a1 b1 c1 c2 c3 d1
$ ./a.sh
a1
b1
c3
d1
$
2
27.01.2020, 21:59

Теги

Похожие вопросы