Рекурсивно создайте каталоги для всех букв

Я предполагаю, что Вы на самом деле вводите

./myBashScript.sh < text.txt

с наклонной чертой вправо.

Когда Вы работаете ./myBashScript.sh < text.txt, Ваша интерактивная оболочка на самом деле получает < text.txt и интерпретирует его как специальную инструкцию – в частности, это интерпретирует Вашу командную строку, чтобы означать, что это должно выполнить myBashScript.sh со стандартным входом, подключенным к text.txt. Ваша оболочка затем удаляет < text.txt из командной строки перед выдаванием управления к myBashScript.sh. Таким образом, насколько Ваш сценарий оболочки затронут, он получает нулевые аргументы, и $2 пусто. Ваш сценарий переводит просто в

echo

который печатает новую строку.

Если Вы хотите на самом деле распечатать название файла, необходимо рассмотреть

#!/bin/sh
echo $1

который можно затем выполнить:

$ ./myShellScript text.txt
text.txt

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

#!/bin/sh
cat $1

который можно затем выполнить:

$ ./myShellScript text.txt
Hello from text.txt, a file containing a bunch of test strings.
12
22.07.2014, 02:48
4 ответа

Попробуйте:

for x in {a..z} ; do mkdir -p $x/${x}{a..z} ; done

Бэш расширит XXX{a..z} до XXXa, XXXb и так далее. Нет необходимости во внутренней петле, которая у вас есть.

After that:

$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
$ ls m
ma  mc  me  mg  mi  mk  mm  mo  mq  ms  mu  mw  my
mb  md  mf  mh  mj  ml  mn  mp  mr  mt  mv  mx  mz
19
27.01.2020, 19:54

В Perl:

perl -MFile::Path=make_path -e '
    make_path(map { $l=$_; map { "$l/$l$_" } a..z } a..z)
'

Файл::Path является основным модулем, так как Perl 5.001.

.
1
27.01.2020, 19:54

Из здесь я создал такой сценарий. Однако, если я получу элегантное решение, я приму его как ответ.

for x in {a..z}
do
    mkdir -p /home/ramesh/$x
    cd /home/ramesh/$x
    for y in {a..z}
    do
        mkdir -p /home/ramesh/$x/$x$y
    done
done
3
27.01.2020, 19:54

Итак, с расширением алфавита bash это работает:

set {a..z}
for a do printf "./$a/$a%s\n" "$@"
done | xargs mkdir -p

И если вы просто напечатаете алфавит один раз в первой строке, то та же самая концепция должна быть переносимой в любую оболочку. Есть и другие способы добраться до строки набора, если вы не хотите набирать ее как:

seq -sP32P 97 123|dc
a b c d e f g h i j k l m n o p q r s t u v w x y z 

...например, работает в ASCII-локации. Так что вы можете сделать установку $(seq -sP32P 97 123|dc) или любую другую команду, которая даст вам $IFS разделенный список аргументов, которые вам нужны, но, я имею в виду, что, вероятно, лучше просто использовать bash вещь или набрать ее.

В любом случае, я думаю, что я бы так и сделал, хотя бы потому, что он вызывает mkdir так часто, как это необходимо.

И просто чтобы продемонстрировать как работает , вот небольшой отладочный вывод меньшего набора:

sh -cx 'for n do printf "./$n/$n%s\n" "$@"; done|cat' -- arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg1/arg1%s\n' arg1 arg2 arg3
+ cat
+ for n in '"$@"'
+ printf './arg2/arg2%s\n' arg1 arg2 arg3
+ for n in '"$@"'
+ printf './arg3/arg3%s\n' arg1 arg2 arg3
./arg1/arg1arg1
./arg1/arg1arg2
./arg1/arg1arg3
./arg2/arg2arg1
./arg2/arg2arg2
./arg2/arg2arg3
./arg3/arg3arg1
./arg3/arg3arg2
./arg3/arg3arg3

Как видите, для только один раз зацикливается на индекс массива позиционных параметров, который я здесь установил простым передачей sh параметров при вызове, а выше с помощью установил ${позиции}. Но printf получает один и тот же массив в списке аргументов для каждой итерации и применяет строку его формата к каждому аргументу, так что вы получаете подобие рекурсии без лишней рекурсии.

И добавление done|command будет передавать по цепочке весь вывод цикла для таким же образом, как done >file будет передавать все это в файл - только открытие и закрытие выходного файла один раз для всей конструкции для...done.

7
27.01.2020, 19:54

Теги

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