Если текущая строка не "Сообщение", то добавить строку в список, объединенный с ОФС; когда вы видите «Сообщение», распечатайте текущий список (, объединенный OFS с текущей строкой «Сообщение»):
awk '/^Message$/ { print t OFS $0 ORS; t=""; } !/^Message$/ { t=(t ? t OFS $0 : $0) }' < foo.txt
Часть t=(t ? t OFS $0 : $0)
является тернарным оператором; он проверяет, не пусто ли t
; если да, то просто присвоить ему текущую строку; в противном случае добавьте к текущему значению OFS, за которым следует текущая строка.
Выход:
some text email@id.com 8903457923 2018-02-09 07:12 (Asia/Kolkata) again some text over here some more text again Message
some text email@id.com 8903457923 2018-02-05 07:12 (Asia/Kolkata) again some text over here some more text again Message
СGNU cp
:
cd src
cp --parents -t../destination components/*/README.md
Обратите внимание, что cp
версия OSX не имеет опции --parents
.
Вы можете использовать rsync
, затем:
rsync -av --include '*/' --include='*/README.md' --exclude='*' src/ destination
Копировать файлы с помощью mmv:
$ mmv -n -c 'src/;README.md' 'destination/#1'
Удалите -n
, когда почувствуете, что готовы копировать файлы.
Скопируйте файлы с помощью find и cpio:
$ find src/ -type f -name README.md -printf %P\\0 | cpio -p -dm0 -D src/ destination/
cpio будет создавать ведущие каталоги там, где это необходимо.
Сначала я подумал, что было бы неплохо, если бы была одна команда, которую я мог бы зарегистрировать как скрипты npm, но в итоге я нашел решение, как показано ниже.
components=(src/components/*)
for dir in "${components[@]}";
do
files=($dir/*.md)
folder_name=${dir##*/}
for file in "${files[@]}";
do
mkdir -p "destination/$folder_name/";
cp "$file" "destination/$folder_name/";
done
done
Использование цикла вbash
:
shopt -s nullglob dotglob globstar
for srcfile in src/**/README.md; do
destfile=destination/${srcfile#src/}
mkdir -p "${destfile%/*}" &&
cp "$srcfile" "$destfile"
done
Здесь мы используем глобус **
(, активируемый установкой параметра оболочки globstar
вbash
)для циклического перебора всех файлов README.md
в любом месте ниже каталога src
.
Для каждого файла путь назначения вычисляется путем замены исходной строки src/
на destination/
. Затем создается целевой каталог и копируется файл.
Параметр оболочки nullglob
гарантирует, что цикл вообще не запустится, если шаблон не соответствует ни одному имени, а параметр dotglob
включает сопоставление скрытых имен.
Если вы хотите скопировать все файлы *.md
, используйте *.md
вместо README.md
в шаблоне.
Вы можете запустить все это как одну команду из любой оболочки, используя
bash -O globstar -O nullglob -O dotglob -c 'for s in src/**/README.md; do d=destination/${s#src/}; mkdir -p "${d%/*}" && cp "$s" "$d"; done'
Использование find
, с дополнительной проверкой, чтобы убедиться, что найденные файлы README.md
являются обычными файлами:
find src -type f -name README.md -exec sh -c '
for srcfile do
destfile=destination/${srcfile#src/}
mkdir -p "${destfile%/*}" &&
cp "$srcfile" "$destfile"
done' sh {} +
Неудивительно, что тело цикла во встроенном sh -c
скрипте идентично циклу в скрипте bash
вверху.
для данной структуры папок... должна работать только эта командная строка
cd src; for i in `find. -name README.md`; do cp $i../destination/$i; done; cd..
Надеюсь, это поможет