#bash #shell
#bash #оболочка
Вопрос:
Я выполняю команду, которая вводит список файлов в моей папке в качестве входных данных. Итак, я выполняю
cat <(for i in ls *chr*.txt; do echo $i; done)
Однако я не хочу включать первую запись из этого списка. Другими словами, я хочу пропустить итерацию 1, поэтому у меня есть только n-1 *chr*.txt
файлов. Как мне это сделать?
Комментарии:
1. Никогда не используйте
ls
таким образом. Смотрите синтаксический анализ2. Обратите внимание, что
echo $i
это также ошибка — это искажает имена файлов, содержащие символы большого размера, пробелы и т.д. Всегда используйтеecho "$i"
или даже лучшеprintf '%sn' "$i"
. Смотрите BashPitfalls #14 .3. Пожалуйста, обратите внимание: Почему не выполнить синтаксический анализ
ls
?4. Звучит как XY . Дайте больше контекста. Что это за имя, которое вы пытаетесь пропустить? Бьюсь об заклад, мы сможем исправить это в глобусе.
Ответ №1:
ls
Здесь вообще не используйте. Поместите ваши файлы в массив, и вы сможете расширить массив, начиная со второго элемента.
files=( *chr*.txt )
printf '%sn' "${files[@]:1}"
В базовых оболочках POSIX, которые не поддерживают массивы, вы можете использовать "$@"
для той же цели, shift
удалив первый элемент:
set -- *chr*.txt # put all names matching the pattern in $1/$2/...
shift # remove $1, putting $2 in its place, moving $3 to $2, etc
printf '%sn' "$@" # print each item from our argument list on a separate line.
Комментарии:
1. @anubhava, хех, ты прав. Я тестировал с
"$@"
, но$0
это особый случай.2. @MAPK, однострочники — плохая идея в bash. Помните, что это язык с почти 50-летним наследием обратной совместимости — обходить все значения по умолчанию, которые были установлены из-за неправильных решений, принятых людьми, внедрявшими оболочки-предшественники десятилетия назад, означает платить высокую цену за детализацию, чтобы добиться правильности. Вы всегда можете поместить
;
между вашими двумя командами, если по какой-то причине вы действительно хотите, чтобы они были в одной строке.
Ответ №2:
Не анализируйте выходные данные ls
.
Вы можете использовать этот один вкладыш:
for i in *chr*.txt; do ((first )) amp;amp; echo "$i"; done
Альтернативно использование массива:
# array holding matching files
arr=(*chr*.txt)
# loop through all but first file
for i in "${arr[@]:1}"; do
echo "$i"
done