Створіть файл та його батьківський каталог


19

Я знаю, що touchкоманда створює файл:

touch test1.txt

але як я можу створити файл та його повний шлях?

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

~/Desktop/$ ls
~/Desktop/$

і я хочу створити 1.txt в ~/Desktop/a/b/c/d/e/f/g/h/1.txt. Чи можу я це зробити за допомогою простої команди, наприклад:

$ touch ~/Desktop/a/b/c/d/e/f/g/h/1.txt

замість того, щоб створити повний шлях вручну, а потім створити файл?

Відповіді:


23

touchне в змозі створити каталоги, mkdirдля цього вам потрібно .

Однак mkdirмає корисний -p/ --parentsваріант, який створює повну структуру каталогу.

Від man mkdir:

   -p, --parents
          no error if existing, make parent directories as needed

Отже, потрібна вам команда у вашій конкретній ситуації:

mkdir -p ~/Desktop/a/b/c/d/e/f/g/h/ && touch ~/Desktop/a/b/c/d/e/f/g/h/1.txt

Якщо ви думаєте, що вам це знадобиться частіше і не хочете вводити шлях двічі кожен раз, ви також можете створити функцію Bash або сценарій для неї.

  • Функція Bash (додайте цей рядок, щоб ~/.bashrcпостійно мати його доступним для вашого користувача, інакше він знову зникне, коли ви виходите з терміналу):

    touch2() { mkdir -p "$(dirname "$1")" && touch "$1" ; }
    

    Його можна просто використовувати так:

    touch2 ~/Desktop/a/b/c/d/e/f/g/h/1.txt
    
  • Сценарій Bash (зберігайте його за /usr/local/bin/touch2допомогою sudo, щоб він був доступний для всіх користувачів, крім того, лише ~/bin/touch2для вашого користувача):

    #!/bin/bash
    mkdir -p "$(dirname "$1")" &&
        touch "$1"
    

    Не забудьте зробити сценарій виконуваним за допомогою chmod +x /PATH/TO/touch2.

    Після цього ви також можете запустити його так:

    touch2 ~/Desktop/a/b/c/d/e/f/g/h/1.txt
    

чи можу я відредагувати оригінальну touch команду та додати -pдо неї перемикач ?
MA Heshmat Khah

3
@HeshmatKhah Це повинно бути можливо, але не рекомендується затінювати системні виконавці своїми власними сценаріями або функціями. Ви можете використовувати ім'я touch-p(немає пробілу!) Замість touch2, якщо ви віддаєте перевагу "p", але я б не намагався замінити початкову команду.
Командир байтів

1
Зауважте, що ви можете скористатися видаленням суфіксів замість того dirname, що можна зробити mkdir -p "${1%/}" && touch "$1", тобто ви могли б зробити так само, як askubuntu.com/a/928544/295286
Сергій Колодяжний

7

Можна використовувати installкоманду з -Dпрапором.

bash-4.3$ install -D /dev/null mydir/one/two

bash-4.3$ tree mydir
mydir
└── one
    └── two

1 directory, 1 file
bash-4.3$ 

Якщо у нас є кілька файлів, ми можемо захотіти скористатися списком елементів (зверніть увагу, не забудьте цитувати предмети з пробілами) та повторити їх:

bash-4.3$ for i in mydir/{'subdir one'/{file1,file2},'subdir 2'/{file3,file4}} ; do 
> install -D /dev/null "$i"
> done
bash-4.3$ tree mydir
mydir
├── one
│   └── two
├── subdir 2
│   ├── file3
│   └── file4
└── subdir one
    ├── file1
    └── file2

Або з масивом:

bash-4.3$ arr=( mydir/{'subdir one'/{file1,file2},'subdir 2'/{file3,file4}} )
bash-4.3$ for i in "${arr[@]}"; do  install -D /dev/null "$i"; done
bash-4.3$ tree mydir
mydir
├── one
│   └── two
├── subdir 2
│   ├── file3
│   └── file4
└── subdir one
    ├── file1
    └── file2

З таким підходом новий файл отримує виконавчі дозволи за замовчуванням. Щоб надати йому такі ж дозволи, які отримали б із дотиком, можна скористатисяinstall -m 644 -D /dev/null <filepath>
ricab

1

Для цього ви можете створити власну функцію, наприклад нижче:

$ echo 'mkfile() { mkdir -p "$(dirname "$1")" && touch "$1" ;  }' >> ~/.bashrc
$ source ~/.bashrc
$ mkfile ./fldr1/fldr2/file.txt

Спочатку вставляємо функцію в кінець файлу ~ / .bashrc за допомогою команди echo. Прапор -p у функції дозволяє створювати вкладені папки, такі як fldr2 з нашого прикладу. Нарешті, ми оновлюємо файл з початковою командою та врешті виконуємо нещодавно створену команду mkfile

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.