Можно сделать это со сценарием оболочки.
Чистый sh - это будет работать даже над оболочками Bourne предPOSIX:
n=1;
max=50;
while [ "$n" -le "$max" ]; do
mkdir "s$n"
n=`expr "$n" + 1`;
done
Если Вы хотите создать высокое количество каталогов, можно сделать сценарий быстрее путем сокращения его до единственного вызова mkdir
а также использование оболочки builtins для тестирования и арифметики. Как это:
n=1
max=50
set -- # this sets $@ [the argv array] to an empty list.
while [ "$n" -le "$max" ]; do
set -- "$@" "s$n" # this adds s$n to the end of $@
n=$(( $n + 1 ));
done
mkdir "$@"
Zsh, ksh93 или удар делают это намного легче, но я должен указать, что это не создается в mkdir
и может не работать в других оболочках. Для больших случаев это может также быть затронуто пределами на число или общий размер аргументов, которые могут быть переданы команде.
mkdir s{1..50}
Оболочки POSIX имеют один массив: позиционные параметры ($1
, $2
, и т.д., коллективно отнесенный в как "$@"
).
set -- 'foo/target/a.jar' 'foo/target/b.jar' 'bar/target/b.jar' 'bar/target/lol whitespace.jar'
set -- "$@" '/another/one at the end.jar'
…
for jar do
dostuffwith "$jar"
done
Это неудобно, потому что существует только один, и это уничтожает любое другое использование позиционных параметров. Позиционные параметры локальны для функции, которая является иногда благословением и иногда проклятием.
Если Ваши имена файлов, как гарантируют, не будут содержать новые строки, можно использовать новые строки в качестве разделителя. Когда Вы разворачиваете переменную, сначала выключаете globbing с set -f
и набор список полевых символов разделения IFS
содержать только новую строку.
INPUT="foo/target/a.jar
foo/target/b.jar
bar/target/b.jar
bar/target/lol whitespace.jar"
…
set -f; IFS='
' # turn off variable value expansion except for splitting at newlines
for jar in $INPUT; do
set +f; unset IFS
dostuffwith "$jar" # restore globbing and field splitting at all whitespace
done
set +f; unset IFS # do it again in case $INPUT was empty
С объектами в Вашем списке, разделенном новыми строками, можно использовать много команд обработки текста полезно в особенности sort
.
Не забудьте всегда помещать двойные кавычки вокруг подстановок переменных, кроме тех случаев, когда Вы явно хотите, чтобы полевое разделение произошло (а также globbing, если Вы не выключили это).
Начиная с Вашего $INPUT
переменная использует новые строки в качестве разделителей, я собираюсь предположить, что Ваши файлы не будут иметь новых строк на имена. По сути, да, существует простой способ выполнить итерации по файлам и сохранить пробел.
Идея состоит в том, чтобы использовать read
встроенная оболочка. Обычно read
разделит на любом пробеле, и таким образом, пробелы повредят его. Но можно установить IFS=$'\n'
и это вместо этого разделит на новых строках только. Таким образом, можно выполнить итерации по каждой строке в списке.
Вот самое маленькое решение, которое я мог предложить:
INPUT="foo/target/a.jar
foo/target/b.jar
bar/target/b.jar
bar/target/lol whitespace.jar"
dostuffwith() {
echo "$1"
}
echo "$INPUT" | awk -F/ '{if (!seen[$NF]++) print }' | \
while IFS=$'\n' read file; do
dostuffwith "$file"
done
В основном это отправляет "$INPUT" в awk
который дедуплицирует на основе имени файла (оно разделяет на /
и затем печатает строку, если последний объект не был замечен прежде). Затем, после того как awk генерировал список путей к файлам, мы используем while read
выполнить итерации через список.
while
цикл, и таким образом dostuffwith
выполняется в подоболочке. Таким образом, любые переменные или изменения, внесенные в рабочую оболочку, будут потеряны, когда цикл завершится. Единственная альтернатива должна использовать полный heredoc, который не настолько неприятен, но я думал, что это будет предпочтительно.
– Patrick
29.11.2013, 00:28
IFS="\n"
разделения на обратной косой черте и n символах. Но в read file
, нет никакого разделения. IFS="\n"
все еще полезно в этом, это удаляет символы пробела из $IFS, который иначе был бы разделен вначале и конец входа. Для чтения строки канонический синтаксис IFS= read -r line
, хотя IFS=anything read -r line
(если что-либо не содержит пробелы), будет работать также.
– Stéphane Chazelas
18.11.2014, 10:31
sort | uniq
ступите работа, как предназначено. вздох – Eero Aaltonen 09.12.2013, 11:52