Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read
Q&A

How to copy files preserving one directory up

+5
−0

Have

mkdir -p d1/d1_sd1/ d2/d2_sd1/
touch d1/d1_sd1/f1.txt d2/d2_sd1/f1.txt
.
├── d1
│   └── d1_sd1
│       └── f1.txt
└── d2
    └── d2_sd1
        └── f1.txt

4 directories, 2 files

Want

.
├── d1
│   └── d1_sd1
│       └── f1.txt
├── d1_sd1
│   └── f1.txt
├── d2
│   └── d2_sd1
│       └── f1.txt
└── d2_sd1
    └── f1.txt

6 directories, 4 files

Question

How do I cp files with a pattern preserving one directory up from the match?

I'd expect a modification to this call:

cp -r d*/*/f1.txt .

Tried

cp -r --parents d*/*/f1.txt .
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

2 comment threads

cp only? Which cp? (5 comments)
./a/b/c/d ---> ./c/d ? (2 comments)

1 answer

+4
−0

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.

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!)

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
Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

Trouble understanding your leaf discussion. (3 comments)

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!

Like what we're doing? Support us! Donate