Рекурсивно «найти» имена файлов, содержащие строки и файлы символических ссылок в другом каталоге.

Для решения на основе awk -:

awk -v FS=, -v OFS=, '{ printf $1; for(i=2;i<=NF;i+=4) { printf OFS $i }; print "";}' marwah.input
3
08.08.2019, 22:58
3 ответа

Для этого я создал короткий скрипт с хорошим выводом, который легко проверить. Нет необходимости создавать структуру каталогов назначения. Используйте следующим образом:

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

Чтобы показать его использование, предположим, что у меня есть следующие файлы/директории в начале:

├── 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

Если я побегу:

$ 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

Я вижу, какие файлы будут связаны. Затем я запускаю скрипт следующим образом:

$./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'

Мое окончательное состояние будет тогда:

├── 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

Вы можете видеть, что каталог destсоздается автоматически, как и все рекурсивные подкаталоги, а в каталоге destбыли связаны только файлы, соответствующие шаблону *_A*.


Здесь исходный код скрипта:

#!/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
2
27.01.2020, 21:11

Если у вас уже есть необходимые каталоги, созданные в целевом расположении, то с реализациями GNU findи xargsэто не так уж сложно:

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

-printf "%P\0"выводит путь с удаленным параметром исходного каталога и заканчивается нулевым байтом.

Затем

xargsсчитывает вывод find.

-0указывает, что используемые параметры разделены нулем -.

--replaceговорит xargs заменить {}аргументом (также подразумевает выполнение одной команды для каждого аргумента ).

Наконец, дается команда заменить аргументы на.

5
27.01.2020, 21:11

Сzsh(предполагается, что целевые каталоги уже существуют):

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

Если ваша lnреализация является реализацией GNU, вы можете использовать ее -rопцию для создания относительных символических ссылок (здесь также -vдля подробных).

zmv -Ls -o-rv ~/path/to/src/'(**/)(*stringtomatch*)' ~/path/to/dst/'$1$2'
1
27.01.2020, 21:11

Теги

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