Welcome to the Power Users community on Codidact!
Power Users is a Q&A site for questions about the usage of computer software and hardware. We are still a small site and would like to grow, so please consider joining our community. We are looking forward to your questions and answers; they are the building blocks of a repository of knowledge we are building together.
Post History
Assuming innermost directories are not empty, in any POSIX compliant system, find . -type d -links 2 -exec cp -r {} . \; In a GNU Linux system, a more performant alternative is find . -type d ...
Answer
#5: Post edited
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- ### How does it work?
- #### Leaf directories have only two hard links
- Every directory in a Linux system is indexed with at least two [hard links][0].
- A leaf directory, by definition a directory without any sub-directory, has only two hard links, `path/to/dir` and `path/to/dir/.`.
On the other hand, a a directory with one sub-directory would have an additional hard link, namely `path/to/dir/subdir/..`.- Conclusion: The number _h_ of hard links of a directory is `h=s+2`, being _s_ the number of sub-directories.
- #### The -exec option
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1 .
- cp -r d3_sd2 .
- while the latter will spawn
- cp -rt . d1_sd1 d3_sd2
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- ### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- ### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [0]: https://en.wikipedia.org/wiki/Hard_link
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- ### How does it work?
- #### Leaf directories have only two hard links
- Every directory in a Linux system is indexed with at least two [hard links][0].
- A leaf directory, by definition a directory without any sub-directory, has only two hard links, `path/to/dir` and `path/to/dir/.`.
- On the other hand, a directory with one sub-directory would have an additional hard link, namely `path/to/dir/subdir/..`.
- Conclusion: The number _h_ of hard links of a directory is `h=s+2`, being _s_ the number of sub-directories.
- #### The -exec option
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1 .
- cp -r d3_sd2 .
- while the latter will spawn
- cp -rt . d1_sd1 d3_sd2
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- ### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- ### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [0]: https://en.wikipedia.org/wiki/Hard_link
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
#4: Post edited
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
#### How does it work?Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories.- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1 .
- cp -r d3_sd2 .
- while the latter will spawn
- cp -rt . d1_sd1 d3_sd2
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
#### Before- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
#### After- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- ### How does it work?
- #### Leaf directories have only two hard links
- Every directory in a Linux system is indexed with at least two [hard links][0].
- A leaf directory, by definition a directory without any sub-directory, has only two hard links, `path/to/dir` and `path/to/dir/.`.
- On the other hand, a a directory with one sub-directory would have an additional hard link, namely `path/to/dir/subdir/..`.
- Conclusion: The number _h_ of hard links of a directory is `h=s+2`, being _s_ the number of sub-directories.
- #### The -exec option
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1 .
- cp -r d3_sd2 .
- while the latter will spawn
- cp -rt . d1_sd1 d3_sd2
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- ### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- ### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [0]: https://en.wikipedia.org/wiki/Hard_link
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
#3: Post edited
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- #### How does it work?
- Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories.
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
cp -r d1_sd1/f1.txt .cp -r d3_sd2/f1.txt .- while the latter will spawn
cp -rt . d1_sd1/f1.txt d3_sd2/f1.txt- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- #### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- #### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- #### How does it work?
- Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories.
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1 .
- cp -r d3_sd2 .
- while the latter will spawn
- cp -rt . d1_sd1 d3_sd2
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- #### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- #### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
#2: Post edited
Assuming innermost directories are not empty,- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- #### How does it work?
- Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories.
- #### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- #### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
```
- Assuming innermost directories are not empty, in any POSIX compliant system,
- find . -type d -links 2 -exec cp -r {} . \;
- In a GNU Linux system, a more performant alternative is
- find . -type d -links 2 -exec cp -rt . {} +
- since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large).
- #### How does it work?
- Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories.
- The `-exec` option executes the corresponding command for each found file if `;` terminated or for the maximum number of files if `+` terminated. So, for example, the first will spawn
- cp -r d1_sd1/f1.txt .
- cp -r d3_sd2/f1.txt .
- while the latter will spawn
- cp -rt . d1_sd1/f1.txt d3_sd2/f1.txt
- See that the latter is only possible because the `-t` option, available in `cp` from GNU coreutils, allows the target to be specified before the files to be copied. ([`-exec cp -r {} . +` is not valid!][1])
- #### Before
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- └── d3/
- └── d3_sd1/
- └── d3_sd2/
- └── f1.txt
- 5 directories, 2 files
- ```
- #### After
- ```
- $ tree
- ./
- ├── d1/
- │ └── d1_sd1/
- │ └── f1.txt
- ├── d1_sd1/
- │ └── f1.txt
- ├── d3/
- │ └── d3_sd1/
- │ └── d3_sd2/
- │ └── f1.txt
- └── d3_sd2/
- └── f1.txt
- 7 directories, 4 files
- ```
- [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html
#1: Initial revision
Assuming innermost directories are not empty, find . -type d -links 2 -exec cp -r {} . \; In a GNU Linux system, a more performant alternative is find . -type d -links 2 -exec cp -rt . {} + since it only spawns an optimal number of `cp` process (a single one if the size of the argument list is not large). #### How does it work? Counting the number of links is a classical way to distinguish leaf directories, that only have 2 of them (one from its parent, `parent/leaf`, and one in itself, `leaf/.`), of other directories. #### Before ``` $ tree ./ ├── d1/ │ └── d1_sd1/ │ └── f1.txt └── d3/ └── d3_sd1/ └── d3_sd2/ └── f1.txt 5 directories, 2 files ``` #### After ``` $ tree ./ ├── d1/ │ └── d1_sd1/ │ └── f1.txt ├── d1_sd1/ │ └── f1.txt ├── d3/ │ └── d3_sd1/ │ └── d3_sd2/ │ └── f1.txt └── d3_sd2/ └── f1.txt 7 directories, 4 files ```