Для решения на основе awk -:
awk -v FS=, -v OFS=, '{ printf $1; for(i=2;i<=NF;i+=4) { printf OFS $i }; print "";}' marwah.input
Для этого я создал короткий скрипт с хорошим выводом, который легко проверить. Нет необходимости создавать структуру каталогов назначения. Используйте следующим образом:
$./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
Если у вас уже есть необходимые каталоги, созданные в целевом расположении, то с реализациями 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 заменить {}
аргументом (также подразумевает выполнение одной команды для каждого аргумента ).
Наконец, дается команда заменить аргументы на.
С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'