Recursively “find” file names containing string and symlink files in another directoryHow to find files containing two strings in different linesbash find: get directory of found fileSymlink files to mirrored directory treeFind Directory if Number of files is over XHow to find files and act on them (find + exec)Make `rsync --link-dest` find files recursivelyunpacking recursively all xlsx files into a new directory containing of the original files nameFind and Replace Colours in CSS Files from Command LineFind and delete files, whilst keeping any matching files if in a specific directoryHow to rename a file to have the same name and extension as another file in same directory

How to compare two different formulations of a problem?

Have only girls been born for a long time in this village?

Was Tuvok bluffing when he said that Voyager's transporters rendered the Kazon weapons useless?

What professions would a medieval village with a population of 100 need?

Does C++20 mandate source code being stored in files?

Are there nouns that change meaning based on gender?

Thread-safe, Convenient and Performant Random Number Generator

Running script line by line automatically yet being asked before each line from second line onwards

jersey vs sweater

How to "know" if I have a passion?

To "hit home" in German

Designing a prison for a telekinetic race

(Why) May a Beit Din refuse to bury a body in order to coerce a man into giving a divorce?

How to dismiss intrusive questions from a colleague with whom I don't work?

How can I run SQL Server Vulnerability Assessment from a SQL Job?

Are there any plans for handling people floating away during an EVA?

Are illustrations in novels frowned upon?

How to determine if an Apex class hasn't been used recently

Can pay be witheld for hours cleaning up after closing time?

In an emergency, how do I find and share my position?

Why doesn't mathematics collapse even though humans quite often make mistakes in their proofs?

Can a group have a cyclical derived series?

What does it mean to have a subnet mask /32?

!I!n!s!e!r!t! !n!b!e!t!w!e!e!n!



Recursively “find” file names containing string and symlink files in another directory


How to find files containing two strings in different linesbash find: get directory of found fileSymlink files to mirrored directory treeFind Directory if Number of files is over XHow to find files and act on them (find + exec)Make `rsync --link-dest` find files recursivelyunpacking recursively all xlsx files into a new directory containing of the original files nameFind and Replace Colours in CSS Files from Command LineFind and delete files, whilst keeping any matching files if in a specific directoryHow to rename a file to have the same name and extension as another file in same directory






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















I am trying to symlink a set of specific files from a project I'm working on.



There is a known string in each of the filenames I wish to symlink.



Here is what I have so far:



ln -s find ~/path/to/src/ -name "*stringtomatch*" find ~/path/to/dest


I have the directory structure setup in the destination to match the source, but it's just directories, so I don't mind deleting those if it's easier to write a command that for an empty destination.



Update:



I have now accepted a working answer and I want to share some context so that a similar use case might find a solution more easily.



I perform the majority of my coding in Netbeans. When I am building packages for a project I tend to name all of the associated files so that they have part of the file name in common. This allows me to easily find my own package files as I move around within the project. However in my current project this is very time consuming due to the large volume of files and directories involved.



What I have now is a separate project defined for each of my own packages which show only the files for that package while maintaining the master project hierarchy.



By building separate package projects that use symlinks to my package files within the master project, I have effectively created what I believe to be the perfect solution where there doesn't seem to be one available within the Netbeans IDE in its current form.



Each sub-project does nothing but allow me to work on a subset of files relating only to itself which really makes my time at the keyboard more efficient.



I believe Eclipse has this feature in-built, though I do not have Eclipse.



So, albeit a compromise I believe that this workaround for Netbeans is as clean a solution I could achieve today. It's a huge bonus that it works as well, if not better than I had anticipated.



I had expected to run manual synchronisations of the master after edits to the sub-projects. This is not the case, the master still maintains automatic synchronisation.










share|improve this question





















  • 1





    I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

    – Inian
    Aug 8 at 7:38


















3















I am trying to symlink a set of specific files from a project I'm working on.



There is a known string in each of the filenames I wish to symlink.



Here is what I have so far:



ln -s find ~/path/to/src/ -name "*stringtomatch*" find ~/path/to/dest


I have the directory structure setup in the destination to match the source, but it's just directories, so I don't mind deleting those if it's easier to write a command that for an empty destination.



Update:



I have now accepted a working answer and I want to share some context so that a similar use case might find a solution more easily.



I perform the majority of my coding in Netbeans. When I am building packages for a project I tend to name all of the associated files so that they have part of the file name in common. This allows me to easily find my own package files as I move around within the project. However in my current project this is very time consuming due to the large volume of files and directories involved.



What I have now is a separate project defined for each of my own packages which show only the files for that package while maintaining the master project hierarchy.



By building separate package projects that use symlinks to my package files within the master project, I have effectively created what I believe to be the perfect solution where there doesn't seem to be one available within the Netbeans IDE in its current form.



Each sub-project does nothing but allow me to work on a subset of files relating only to itself which really makes my time at the keyboard more efficient.



I believe Eclipse has this feature in-built, though I do not have Eclipse.



So, albeit a compromise I believe that this workaround for Netbeans is as clean a solution I could achieve today. It's a huge bonus that it works as well, if not better than I had anticipated.



I had expected to run manual synchronisations of the master after edits to the sub-projects. This is not the case, the master still maintains automatic synchronisation.










share|improve this question





















  • 1





    I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

    – Inian
    Aug 8 at 7:38














3












3








3








I am trying to symlink a set of specific files from a project I'm working on.



There is a known string in each of the filenames I wish to symlink.



Here is what I have so far:



ln -s find ~/path/to/src/ -name "*stringtomatch*" find ~/path/to/dest


I have the directory structure setup in the destination to match the source, but it's just directories, so I don't mind deleting those if it's easier to write a command that for an empty destination.



Update:



I have now accepted a working answer and I want to share some context so that a similar use case might find a solution more easily.



I perform the majority of my coding in Netbeans. When I am building packages for a project I tend to name all of the associated files so that they have part of the file name in common. This allows me to easily find my own package files as I move around within the project. However in my current project this is very time consuming due to the large volume of files and directories involved.



What I have now is a separate project defined for each of my own packages which show only the files for that package while maintaining the master project hierarchy.



By building separate package projects that use symlinks to my package files within the master project, I have effectively created what I believe to be the perfect solution where there doesn't seem to be one available within the Netbeans IDE in its current form.



Each sub-project does nothing but allow me to work on a subset of files relating only to itself which really makes my time at the keyboard more efficient.



I believe Eclipse has this feature in-built, though I do not have Eclipse.



So, albeit a compromise I believe that this workaround for Netbeans is as clean a solution I could achieve today. It's a huge bonus that it works as well, if not better than I had anticipated.



I had expected to run manual synchronisations of the master after edits to the sub-projects. This is not the case, the master still maintains automatic synchronisation.










share|improve this question
















I am trying to symlink a set of specific files from a project I'm working on.



There is a known string in each of the filenames I wish to symlink.



Here is what I have so far:



ln -s find ~/path/to/src/ -name "*stringtomatch*" find ~/path/to/dest


I have the directory structure setup in the destination to match the source, but it's just directories, so I don't mind deleting those if it's easier to write a command that for an empty destination.



Update:



I have now accepted a working answer and I want to share some context so that a similar use case might find a solution more easily.



I perform the majority of my coding in Netbeans. When I am building packages for a project I tend to name all of the associated files so that they have part of the file name in common. This allows me to easily find my own package files as I move around within the project. However in my current project this is very time consuming due to the large volume of files and directories involved.



What I have now is a separate project defined for each of my own packages which show only the files for that package while maintaining the master project hierarchy.



By building separate package projects that use symlinks to my package files within the master project, I have effectively created what I believe to be the perfect solution where there doesn't seem to be one available within the Netbeans IDE in its current form.



Each sub-project does nothing but allow me to work on a subset of files relating only to itself which really makes my time at the keyboard more efficient.



I believe Eclipse has this feature in-built, though I do not have Eclipse.



So, albeit a compromise I believe that this workaround for Netbeans is as clean a solution I could achieve today. It's a huge bonus that it works as well, if not better than I had anticipated.



I had expected to run manual synchronisations of the master after edits to the sub-projects. This is not the case, the master still maintains automatic synchronisation.







find symlink ln






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 8 at 19:58







Chris

















asked Aug 8 at 7:08









ChrisChris

1185 bronze badges




1185 bronze badges










  • 1





    I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

    – Inian
    Aug 8 at 7:38













  • 1





    I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

    – Inian
    Aug 8 at 7:38








1




1





I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

– Inian
Aug 8 at 7:38






I've deleted my answer, since I'm still working on to find how to preserve the path in the destination

– Inian
Aug 8 at 7:38











3 Answers
3






active

oldest

votes


















2














I created a short script to do this, with a nice output which should be easy check the results. It doesn't need to have the destination directory structure created. Use as follows:



$ ./recursive-symlink.sh --help
Usage:
./recursive-symlink.sh <source_path> <dest_path> <find_args...>


To show its usage, let's say I have the following files/dirs at the begining:



├── recursive-symlink.sh*
└── src/
├── dir1/
│   ├── file_A_misc.txt
│   └── file_B_sub.txt
├── dir3/
│   ├── file_A3.txt
│   ├── file_C.txt
│   └── subsub_dir/
│   ├── file_Asubsub.txt
│   └── file_D.txt
├── dir_A/
│   └── should_be_empty.dat
├── file_A.txt
└── file_B.txt


If I run:



$ find -name '*_A*'
./src/file_A.txt
./src/dir3/file_A3.txt
./src/dir3/subsub_dir/file_Asubsub.txt
./src/dir_A
./src/dir1/file_A_misc.txt


I can see which files would be linked. I then run the script like this:



$ ./recursive-symlink.sh src/ dest/ -name '*_A*'
src/file_A.txt
mkdir: created directory 'dest'
'dest/file_A.txt' -> '../src/file_A.txt'

src/dir3/file_A3.txt
mkdir: created directory 'dest/dir3'
'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt'

src/dir3/subsub_dir/file_Asubsub.txt
mkdir: created directory 'dest/dir3/subsub_dir'
'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt'

src/dir_A
'dest/dir_A' -> '../src/dir_A'

src/dir1/file_A_misc.txt
mkdir: created directory 'dest/dir1'
'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'



My final state will be then:



├── recursive-symlink.sh*
├── src/
│ ├── dir1/
│ │   ├── file_A_misc.txt
│ │   └── file_B_sub.txt
│ ├── dir3/
│ │   ├── file_A3.txt
│ │   ├── file_C.txt
│ │   └── subsub_dir/
│ │   ├── file_Asubsub.txt
│ │   └── file_D.txt
│ ├── dir_A/
│ │   └── should_be_empty.dat
│ ├── file_A.txt
│ └── file_B.txt
└── dest/
    ├── dir1/
    │   └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt
    ├── dir3/
    │   ├── file_A3.txt -> ../../src/dir3/file_A3.txt
    │   └── subsub_dir/
    │   └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt
    ├── dir_A -> ../src/dir_A/
    └── file_A.txt -> ../src/file_A.txt


You can see that dest directory is created automatically, as well all recursive subdirectories, and on the dest dir, only the files that matched the *_A* pattern were linked.




Here the script source code:



#!/bin/bash

verbose='-v' # you may comment this line

if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ]
then
echo "Usage:"
echo " $0 <source_path> <dest_path> <find_args...>"
exit
fi

src="$1%/" ; shift
dest="$1%/" ; shift
relflag='' ; [ "$src:0:1" != '/' ] && relflag='-r'

find "$src" ( "$@" ) -print0 |
while IFS= read -r -d '' f
do
base_fname="$f#$src"
[ "$verbose" ] && echo "$f"
dest_ln="$dest/$base_fname#/"
dest_dir="$(dirname "$dest_ln")"
mkdir -p $verbose "$dest_dir"
ln $relflag -s $verbose -t "$dest_dir" "$f"
[ "$verbose" ] && echo
done





share|improve this answer

























  • I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

    – Chris
    Aug 8 at 17:42






  • 1





    Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

    – Fabiano
    Aug 8 at 20:41











  • This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

    – Fabiano
    Aug 8 at 20:42


















5














If you already have the necessary directories created in the target location, then with the GNU implementations of find and xargs, it's not too difficult:



find ~/path/to/src -name "*stringtomatch*" -printf "%P" |
xargs -r0 --replace ln -s ~/path/to/src/'' ~/path/to/dest/''


The -printf "%P" outputs the path with the source directory parameter removed, and ends with a null byte.



xargs then reads the find output.



-0 indicates the parameters to use are null-separated.



--replace tells xargs to replace with the argument (also implies running one command per argument).



Finally the command to replace arguments into is given.






share|improve this answer



























  • the %P is very neat!!

    – Fabiano
    Aug 8 at 20:44


















1














With zsh (assuming the target directories already exist):



autoload zmv # best in ~/.zshrc
zmv -Ls ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'


If your ln implementation is the GNU one, you can use its -r option to make relative symlinks (here also -v for verbose).



zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'





share|improve this answer



























    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f534489%2frecursively-find-file-names-containing-string-and-symlink-files-in-another-dir%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    I created a short script to do this, with a nice output which should be easy check the results. It doesn't need to have the destination directory structure created. Use as follows:



    $ ./recursive-symlink.sh --help
    Usage:
    ./recursive-symlink.sh <source_path> <dest_path> <find_args...>


    To show its usage, let's say I have the following files/dirs at the begining:



    ├── recursive-symlink.sh*
    └── src/
    ├── dir1/
    │   ├── file_A_misc.txt
    │   └── file_B_sub.txt
    ├── dir3/
    │   ├── file_A3.txt
    │   ├── file_C.txt
    │   └── subsub_dir/
    │   ├── file_Asubsub.txt
    │   └── file_D.txt
    ├── dir_A/
    │   └── should_be_empty.dat
    ├── file_A.txt
    └── file_B.txt


    If I run:



    $ find -name '*_A*'
    ./src/file_A.txt
    ./src/dir3/file_A3.txt
    ./src/dir3/subsub_dir/file_Asubsub.txt
    ./src/dir_A
    ./src/dir1/file_A_misc.txt


    I can see which files would be linked. I then run the script like this:



    $ ./recursive-symlink.sh src/ dest/ -name '*_A*'
    src/file_A.txt
    mkdir: created directory 'dest'
    'dest/file_A.txt' -> '../src/file_A.txt'

    src/dir3/file_A3.txt
    mkdir: created directory 'dest/dir3'
    'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt'

    src/dir3/subsub_dir/file_Asubsub.txt
    mkdir: created directory 'dest/dir3/subsub_dir'
    'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt'

    src/dir_A
    'dest/dir_A' -> '../src/dir_A'

    src/dir1/file_A_misc.txt
    mkdir: created directory 'dest/dir1'
    'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'



    My final state will be then:



    ├── recursive-symlink.sh*
    ├── src/
    │ ├── dir1/
    │ │   ├── file_A_misc.txt
    │ │   └── file_B_sub.txt
    │ ├── dir3/
    │ │   ├── file_A3.txt
    │ │   ├── file_C.txt
    │ │   └── subsub_dir/
    │ │   ├── file_Asubsub.txt
    │ │   └── file_D.txt
    │ ├── dir_A/
    │ │   └── should_be_empty.dat
    │ ├── file_A.txt
    │ └── file_B.txt
    └── dest/
        ├── dir1/
        │   └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt
        ├── dir3/
        │   ├── file_A3.txt -> ../../src/dir3/file_A3.txt
        │   └── subsub_dir/
        │   └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt
        ├── dir_A -> ../src/dir_A/
        └── file_A.txt -> ../src/file_A.txt


    You can see that dest directory is created automatically, as well all recursive subdirectories, and on the dest dir, only the files that matched the *_A* pattern were linked.




    Here the script source code:



    #!/bin/bash

    verbose='-v' # you may comment this line

    if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ]
    then
    echo "Usage:"
    echo " $0 <source_path> <dest_path> <find_args...>"
    exit
    fi

    src="$1%/" ; shift
    dest="$1%/" ; shift
    relflag='' ; [ "$src:0:1" != '/' ] && relflag='-r'

    find "$src" ( "$@" ) -print0 |
    while IFS= read -r -d '' f
    do
    base_fname="$f#$src"
    [ "$verbose" ] && echo "$f"
    dest_ln="$dest/$base_fname#/"
    dest_dir="$(dirname "$dest_ln")"
    mkdir -p $verbose "$dest_dir"
    ln $relflag -s $verbose -t "$dest_dir" "$f"
    [ "$verbose" ] && echo
    done





    share|improve this answer

























    • I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

      – Chris
      Aug 8 at 17:42






    • 1





      Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

      – Fabiano
      Aug 8 at 20:41











    • This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

      – Fabiano
      Aug 8 at 20:42















    2














    I created a short script to do this, with a nice output which should be easy check the results. It doesn't need to have the destination directory structure created. Use as follows:



    $ ./recursive-symlink.sh --help
    Usage:
    ./recursive-symlink.sh <source_path> <dest_path> <find_args...>


    To show its usage, let's say I have the following files/dirs at the begining:



    ├── recursive-symlink.sh*
    └── src/
    ├── dir1/
    │   ├── file_A_misc.txt
    │   └── file_B_sub.txt
    ├── dir3/
    │   ├── file_A3.txt
    │   ├── file_C.txt
    │   └── subsub_dir/
    │   ├── file_Asubsub.txt
    │   └── file_D.txt
    ├── dir_A/
    │   └── should_be_empty.dat
    ├── file_A.txt
    └── file_B.txt


    If I run:



    $ find -name '*_A*'
    ./src/file_A.txt
    ./src/dir3/file_A3.txt
    ./src/dir3/subsub_dir/file_Asubsub.txt
    ./src/dir_A
    ./src/dir1/file_A_misc.txt


    I can see which files would be linked. I then run the script like this:



    $ ./recursive-symlink.sh src/ dest/ -name '*_A*'
    src/file_A.txt
    mkdir: created directory 'dest'
    'dest/file_A.txt' -> '../src/file_A.txt'

    src/dir3/file_A3.txt
    mkdir: created directory 'dest/dir3'
    'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt'

    src/dir3/subsub_dir/file_Asubsub.txt
    mkdir: created directory 'dest/dir3/subsub_dir'
    'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt'

    src/dir_A
    'dest/dir_A' -> '../src/dir_A'

    src/dir1/file_A_misc.txt
    mkdir: created directory 'dest/dir1'
    'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'



    My final state will be then:



    ├── recursive-symlink.sh*
    ├── src/
    │ ├── dir1/
    │ │   ├── file_A_misc.txt
    │ │   └── file_B_sub.txt
    │ ├── dir3/
    │ │   ├── file_A3.txt
    │ │   ├── file_C.txt
    │ │   └── subsub_dir/
    │ │   ├── file_Asubsub.txt
    │ │   └── file_D.txt
    │ ├── dir_A/
    │ │   └── should_be_empty.dat
    │ ├── file_A.txt
    │ └── file_B.txt
    └── dest/
        ├── dir1/
        │   └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt
        ├── dir3/
        │   ├── file_A3.txt -> ../../src/dir3/file_A3.txt
        │   └── subsub_dir/
        │   └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt
        ├── dir_A -> ../src/dir_A/
        └── file_A.txt -> ../src/file_A.txt


    You can see that dest directory is created automatically, as well all recursive subdirectories, and on the dest dir, only the files that matched the *_A* pattern were linked.




    Here the script source code:



    #!/bin/bash

    verbose='-v' # you may comment this line

    if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ]
    then
    echo "Usage:"
    echo " $0 <source_path> <dest_path> <find_args...>"
    exit
    fi

    src="$1%/" ; shift
    dest="$1%/" ; shift
    relflag='' ; [ "$src:0:1" != '/' ] && relflag='-r'

    find "$src" ( "$@" ) -print0 |
    while IFS= read -r -d '' f
    do
    base_fname="$f#$src"
    [ "$verbose" ] && echo "$f"
    dest_ln="$dest/$base_fname#/"
    dest_dir="$(dirname "$dest_ln")"
    mkdir -p $verbose "$dest_dir"
    ln $relflag -s $verbose -t "$dest_dir" "$f"
    [ "$verbose" ] && echo
    done





    share|improve this answer

























    • I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

      – Chris
      Aug 8 at 17:42






    • 1





      Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

      – Fabiano
      Aug 8 at 20:41











    • This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

      – Fabiano
      Aug 8 at 20:42













    2












    2








    2







    I created a short script to do this, with a nice output which should be easy check the results. It doesn't need to have the destination directory structure created. Use as follows:



    $ ./recursive-symlink.sh --help
    Usage:
    ./recursive-symlink.sh <source_path> <dest_path> <find_args...>


    To show its usage, let's say I have the following files/dirs at the begining:



    ├── recursive-symlink.sh*
    └── src/
    ├── dir1/
    │   ├── file_A_misc.txt
    │   └── file_B_sub.txt
    ├── dir3/
    │   ├── file_A3.txt
    │   ├── file_C.txt
    │   └── subsub_dir/
    │   ├── file_Asubsub.txt
    │   └── file_D.txt
    ├── dir_A/
    │   └── should_be_empty.dat
    ├── file_A.txt
    └── file_B.txt


    If I run:



    $ find -name '*_A*'
    ./src/file_A.txt
    ./src/dir3/file_A3.txt
    ./src/dir3/subsub_dir/file_Asubsub.txt
    ./src/dir_A
    ./src/dir1/file_A_misc.txt


    I can see which files would be linked. I then run the script like this:



    $ ./recursive-symlink.sh src/ dest/ -name '*_A*'
    src/file_A.txt
    mkdir: created directory 'dest'
    'dest/file_A.txt' -> '../src/file_A.txt'

    src/dir3/file_A3.txt
    mkdir: created directory 'dest/dir3'
    'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt'

    src/dir3/subsub_dir/file_Asubsub.txt
    mkdir: created directory 'dest/dir3/subsub_dir'
    'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt'

    src/dir_A
    'dest/dir_A' -> '../src/dir_A'

    src/dir1/file_A_misc.txt
    mkdir: created directory 'dest/dir1'
    'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'



    My final state will be then:



    ├── recursive-symlink.sh*
    ├── src/
    │ ├── dir1/
    │ │   ├── file_A_misc.txt
    │ │   └── file_B_sub.txt
    │ ├── dir3/
    │ │   ├── file_A3.txt
    │ │   ├── file_C.txt
    │ │   └── subsub_dir/
    │ │   ├── file_Asubsub.txt
    │ │   └── file_D.txt
    │ ├── dir_A/
    │ │   └── should_be_empty.dat
    │ ├── file_A.txt
    │ └── file_B.txt
    └── dest/
        ├── dir1/
        │   └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt
        ├── dir3/
        │   ├── file_A3.txt -> ../../src/dir3/file_A3.txt
        │   └── subsub_dir/
        │   └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt
        ├── dir_A -> ../src/dir_A/
        └── file_A.txt -> ../src/file_A.txt


    You can see that dest directory is created automatically, as well all recursive subdirectories, and on the dest dir, only the files that matched the *_A* pattern were linked.




    Here the script source code:



    #!/bin/bash

    verbose='-v' # you may comment this line

    if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ]
    then
    echo "Usage:"
    echo " $0 <source_path> <dest_path> <find_args...>"
    exit
    fi

    src="$1%/" ; shift
    dest="$1%/" ; shift
    relflag='' ; [ "$src:0:1" != '/' ] && relflag='-r'

    find "$src" ( "$@" ) -print0 |
    while IFS= read -r -d '' f
    do
    base_fname="$f#$src"
    [ "$verbose" ] && echo "$f"
    dest_ln="$dest/$base_fname#/"
    dest_dir="$(dirname "$dest_ln")"
    mkdir -p $verbose "$dest_dir"
    ln $relflag -s $verbose -t "$dest_dir" "$f"
    [ "$verbose" ] && echo
    done





    share|improve this answer













    I created a short script to do this, with a nice output which should be easy check the results. It doesn't need to have the destination directory structure created. Use as follows:



    $ ./recursive-symlink.sh --help
    Usage:
    ./recursive-symlink.sh <source_path> <dest_path> <find_args...>


    To show its usage, let's say I have the following files/dirs at the begining:



    ├── recursive-symlink.sh*
    └── src/
    ├── dir1/
    │   ├── file_A_misc.txt
    │   └── file_B_sub.txt
    ├── dir3/
    │   ├── file_A3.txt
    │   ├── file_C.txt
    │   └── subsub_dir/
    │   ├── file_Asubsub.txt
    │   └── file_D.txt
    ├── dir_A/
    │   └── should_be_empty.dat
    ├── file_A.txt
    └── file_B.txt


    If I run:



    $ find -name '*_A*'
    ./src/file_A.txt
    ./src/dir3/file_A3.txt
    ./src/dir3/subsub_dir/file_Asubsub.txt
    ./src/dir_A
    ./src/dir1/file_A_misc.txt


    I can see which files would be linked. I then run the script like this:



    $ ./recursive-symlink.sh src/ dest/ -name '*_A*'
    src/file_A.txt
    mkdir: created directory 'dest'
    'dest/file_A.txt' -> '../src/file_A.txt'

    src/dir3/file_A3.txt
    mkdir: created directory 'dest/dir3'
    'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt'

    src/dir3/subsub_dir/file_Asubsub.txt
    mkdir: created directory 'dest/dir3/subsub_dir'
    'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt'

    src/dir_A
    'dest/dir_A' -> '../src/dir_A'

    src/dir1/file_A_misc.txt
    mkdir: created directory 'dest/dir1'
    'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'



    My final state will be then:



    ├── recursive-symlink.sh*
    ├── src/
    │ ├── dir1/
    │ │   ├── file_A_misc.txt
    │ │   └── file_B_sub.txt
    │ ├── dir3/
    │ │   ├── file_A3.txt
    │ │   ├── file_C.txt
    │ │   └── subsub_dir/
    │ │   ├── file_Asubsub.txt
    │ │   └── file_D.txt
    │ ├── dir_A/
    │ │   └── should_be_empty.dat
    │ ├── file_A.txt
    │ └── file_B.txt
    └── dest/
        ├── dir1/
        │   └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt
        ├── dir3/
        │   ├── file_A3.txt -> ../../src/dir3/file_A3.txt
        │   └── subsub_dir/
        │   └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt
        ├── dir_A -> ../src/dir_A/
        └── file_A.txt -> ../src/file_A.txt


    You can see that dest directory is created automatically, as well all recursive subdirectories, and on the dest dir, only the files that matched the *_A* pattern were linked.




    Here the script source code:



    #!/bin/bash

    verbose='-v' # you may comment this line

    if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ]
    then
    echo "Usage:"
    echo " $0 <source_path> <dest_path> <find_args...>"
    exit
    fi

    src="$1%/" ; shift
    dest="$1%/" ; shift
    relflag='' ; [ "$src:0:1" != '/' ] && relflag='-r'

    find "$src" ( "$@" ) -print0 |
    while IFS= read -r -d '' f
    do
    base_fname="$f#$src"
    [ "$verbose" ] && echo "$f"
    dest_ln="$dest/$base_fname#/"
    dest_dir="$(dirname "$dest_ln")"
    mkdir -p $verbose "$dest_dir"
    ln $relflag -s $verbose -t "$dest_dir" "$f"
    [ "$verbose" ] && echo
    done






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Aug 8 at 10:22









    FabianoFabiano

    1461 bronze badge




    1461 bronze badge















    • I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

      – Chris
      Aug 8 at 17:42






    • 1





      Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

      – Fabiano
      Aug 8 at 20:41











    • This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

      – Fabiano
      Aug 8 at 20:42

















    • I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

      – Chris
      Aug 8 at 17:42






    • 1





      Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

      – Fabiano
      Aug 8 at 20:41











    • This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

      – Fabiano
      Aug 8 at 20:42
















    I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

    – Chris
    Aug 8 at 17:42





    I don't know that this is the best answer, but i do like the script option because it means all i need to do is read a comment in the file and I can remember exactly how to use it in the future. So thank you, for that reason I have accepted your answer.

    – Chris
    Aug 8 at 17:42




    1




    1





    Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

    – Fabiano
    Aug 8 at 20:41





    Hi @Chris, thanks, that's actually why I do lots of utility scripts, even if they are just a couple lines, it's common to have the same problems over and over again, and sometimes, even for just a one-liner, you end up spending some fair amount of time to get it right, I usually do those directly on the interactive shell and when they are working, I put on a file, parametrize them a bit and add a "Usage: " help. Months later this saves me many hours of re-work..

    – Fabiano
    Aug 8 at 20:41













    This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

    – Fabiano
    Aug 8 at 20:42





    This one for example I also started as a one-liner, similar to @wurtel's (but four commands instead of three: find, while, ln plus the additional mkdir), the rest is just some boiler plate to treat corner cases (like filenames with exotic chars such as n, handle both absolute and relative paths, verbosity, accept multiple parameters to the find, etc) and then it becomes pretty hard to read and understand a few days later..

    – Fabiano
    Aug 8 at 20:42













    5














    If you already have the necessary directories created in the target location, then with the GNU implementations of find and xargs, it's not too difficult:



    find ~/path/to/src -name "*stringtomatch*" -printf "%P" |
    xargs -r0 --replace ln -s ~/path/to/src/'' ~/path/to/dest/''


    The -printf "%P" outputs the path with the source directory parameter removed, and ends with a null byte.



    xargs then reads the find output.



    -0 indicates the parameters to use are null-separated.



    --replace tells xargs to replace with the argument (also implies running one command per argument).



    Finally the command to replace arguments into is given.






    share|improve this answer



























    • the %P is very neat!!

      – Fabiano
      Aug 8 at 20:44















    5














    If you already have the necessary directories created in the target location, then with the GNU implementations of find and xargs, it's not too difficult:



    find ~/path/to/src -name "*stringtomatch*" -printf "%P" |
    xargs -r0 --replace ln -s ~/path/to/src/'' ~/path/to/dest/''


    The -printf "%P" outputs the path with the source directory parameter removed, and ends with a null byte.



    xargs then reads the find output.



    -0 indicates the parameters to use are null-separated.



    --replace tells xargs to replace with the argument (also implies running one command per argument).



    Finally the command to replace arguments into is given.






    share|improve this answer



























    • the %P is very neat!!

      – Fabiano
      Aug 8 at 20:44













    5












    5








    5







    If you already have the necessary directories created in the target location, then with the GNU implementations of find and xargs, it's not too difficult:



    find ~/path/to/src -name "*stringtomatch*" -printf "%P" |
    xargs -r0 --replace ln -s ~/path/to/src/'' ~/path/to/dest/''


    The -printf "%P" outputs the path with the source directory parameter removed, and ends with a null byte.



    xargs then reads the find output.



    -0 indicates the parameters to use are null-separated.



    --replace tells xargs to replace with the argument (also implies running one command per argument).



    Finally the command to replace arguments into is given.






    share|improve this answer















    If you already have the necessary directories created in the target location, then with the GNU implementations of find and xargs, it's not too difficult:



    find ~/path/to/src -name "*stringtomatch*" -printf "%P" |
    xargs -r0 --replace ln -s ~/path/to/src/'' ~/path/to/dest/''


    The -printf "%P" outputs the path with the source directory parameter removed, and ends with a null byte.



    xargs then reads the find output.



    -0 indicates the parameters to use are null-separated.



    --replace tells xargs to replace with the argument (also implies running one command per argument).



    Finally the command to replace arguments into is given.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 8 at 9:40









    Stéphane Chazelas

    330k58 gold badges642 silver badges1010 bronze badges




    330k58 gold badges642 silver badges1010 bronze badges










    answered Aug 8 at 9:20









    wurtelwurtel

    11.8k1 gold badge16 silver badges29 bronze badges




    11.8k1 gold badge16 silver badges29 bronze badges















    • the %P is very neat!!

      – Fabiano
      Aug 8 at 20:44

















    • the %P is very neat!!

      – Fabiano
      Aug 8 at 20:44
















    the %P is very neat!!

    – Fabiano
    Aug 8 at 20:44





    the %P is very neat!!

    – Fabiano
    Aug 8 at 20:44











    1














    With zsh (assuming the target directories already exist):



    autoload zmv # best in ~/.zshrc
    zmv -Ls ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'


    If your ln implementation is the GNU one, you can use its -r option to make relative symlinks (here also -v for verbose).



    zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'





    share|improve this answer





























      1














      With zsh (assuming the target directories already exist):



      autoload zmv # best in ~/.zshrc
      zmv -Ls ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'


      If your ln implementation is the GNU one, you can use its -r option to make relative symlinks (here also -v for verbose).



      zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'





      share|improve this answer



























        1












        1








        1







        With zsh (assuming the target directories already exist):



        autoload zmv # best in ~/.zshrc
        zmv -Ls ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'


        If your ln implementation is the GNU one, you can use its -r option to make relative symlinks (here also -v for verbose).



        zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'





        share|improve this answer













        With zsh (assuming the target directories already exist):



        autoload zmv # best in ~/.zshrc
        zmv -Ls ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'


        If your ln implementation is the GNU one, you can use its -r option to make relative symlinks (here also -v for verbose).



        zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Aug 8 at 9:45









        Stéphane ChazelasStéphane Chazelas

        330k58 gold badges642 silver badges1010 bronze badges




        330k58 gold badges642 silver badges1010 bronze badges






























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f534489%2frecursively-find-file-names-containing-string-and-symlink-files-in-another-dir%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Grendel Contents Story Scholarship Depictions Notes References Navigation menu10.1093/notesj/gjn112Berserkeree

            Area configuration aggregation error after install Porto themeMagento 2.1 CE Installed but front/backend not loading/workingCSS not loading on page within Magento 2 pageCannot install module in Magento 2no commands defined in the “setup” namespace. in Magento2Magento 2: Static files are present but shows 404Why do i have to always run the commands to clean cache in Magento 2.1.8?Failure reason: 'Unable to unserialize value.'Error 500 after magento migrationIn production mode the site does not loadMagento 2 : Error 500 after installing

            Middle Expansion Olielle Resaix Definition: Uttering songs of triumph shouting with joy triumphant exulting Sejunction Journal 붙다 달 고급 품목 외출 The stretch trades the screeching tin. Definition: The act of speaking with a drawl a drawl Cough Sand Definition: An uproar a quarrel a noisy outbreak Shake Iron Publicize Horse House Baby 사과 Resaix Flaggy Jelly Temporary Unequaled Puppet A drop in the bucket Shrew 성격 회원 성질 미팅 The burn frames the tacky quality. Materialistic The smoke reduces the way. Yammoe Nondescript Cheek 얼굴 배 약하다 날리다 타다 The illegal country shows the iron. Help Rule Drearien Smoke Teaching Meaty Wasp Abraham Lincoln Jaws 진심 수리하다 Size Cork Idea Convert Think Lark John Lennon 거울 청소 군 추천하다 아이스크림