Если найден шаблон, как вставить последнюю строку перед тем, как он содержит другой шаблон в bash? - PullRequest
1 голос
/ 18 апреля 2019

После помещения списка всех папок и подпапок в list.txt с помощью команды ls -R, у меня есть такие данные:

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_Diadematidae/Sp_01:
 DSCF0214.JPG
 DSCF0215.JPG
 DSCF0231.JPG

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae:
 Sp_02
 Sp_03

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_02:
 DSCF8981.JPG
 DSCF8988.JPG

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_03:
 DSCF0638.JPG

 Invertebrates/Phylum_echinoderma/Class_Holothuroidea/Fam_Stichopodidae:
 Sp_07

 Invertebrates/Phylum_echinoderma/Class_Holothuroidea/Fam_Stichopodidae/Sp_07:
 DSCF0724.JPG

Я хотел бы добавить строковый код, который позволит добавить путь перед изображениями ("XXX.JPG"). Поэтому я попытался сказать в bash: «если есть шаблон« .JPG », вставьте перед именем изображения« последнюю строку перед », содержащую« / Sp * ». И замените : на /. Чтобы получить это:

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_Diadematidae/Sp_01:
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_Diadematidae/Sp_01/DSCF0214.JPG
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_Diadematidae/Sp_01/DSCF0215.JPG
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_Diadematidae/Sp_01/DSCF0231.JPG

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae:
 Sp_02
 Sp_03

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_02:
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_02/DSCF8981.JPG
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_02/DSCF8988.JPG

 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_03
 Invertebrates/Phylum_echinoderma/Class_Echinoidea/Fam_PasDiadematidae/Sp_03/DSCF0638.JPG

 Invertebrates/Phylum_echinoderma/Class_Holothuroidea/Fam_Stichopodidae:
 Sp_07

 Invertebrates/Phylum_echinoderma/Class_Holothuroidea/Fam_Stichopodidae/Sp_07:
 Invertebrates/Phylum_echinoderma/Class_Holothuroidea/Fam_Stichopodidae/Sp_07/DSCF0724.JPG

Я не нашел способа объяснить bash «последнюю строку перед», содержащую «/ Sp *». Это мой код:

 # Find the .JPG pattern and catch the picture name ("(.*\).JPG") and add "the last line before" that contain "/Sp*" and reput the .JPG pattern with the picture name:
 sed 's/\(.*\).JPG/"the last line before" that contain "/Sp*""\1.JPG/' list.txt > list2.txt
 sed -e 's/\:/\//g' list2.txt > list3.txt

Любой совет, который поможет мне завершить эту часть кода, очень важен.

Ответы [ 4 ]

2 голосов
/ 18 апреля 2019

Хотя есть лучшая альтернатива для получения списка файлов, если это не вариант, для вас есть конкретная проблема, если бы вы написали простой скрипт bash.

prefix=""
outfile=list2.txt
> $outfile  # clean any existing file content, remove if not expected
while read -r line; do
    if [[ $line =~ (.*):$ ]]; then
        echo $line >> $outfile
        prefix="${BASH_REMATCH[1]}"
    elif [[ $line =~ \.JPG$ ]]; then
        echo "${prefix}/${line}" >> $outfile
    else
        echo "${line}" >> $outfile
    fi
done < list.txt
1 голос
/ 19 апреля 2019

если ваши данные в файле 'd', попробуйте gnu sed:

sed -E '/Sp_[0-9]+:$/{h;p;:c N;/\.JPG$/{s!:\n\s*!/!p;g;bc}; z}' d
1 голос
/ 18 апреля 2019

Хотя ошибочно, это можно сделать с sed:

sed -n -e '/:$/{p;s@:$@/@;h}' -e '/\.JPG$/{H;x;h;s/\n//;p;x;s/\n.*//;h}'

Вы можете попробовать здесь .

Первое выражение используется при обнаружении каталога (на основе того факта, что строка заканчивается на :), печатает его и сохраняет путь к каталогу в буфере удержания после замены : на / путь-разделитель.

Второе выражение используется при обнаружении файла .JPG и выполняет следующую последовательность действий:

  • добавляет строку в буфер удержания (пространство шаблона: picture.JPG; буфер удержания: dir/\npicture.JPG)
  • обмен пространством шаблона и буфером хранения (пространство шаблона: dir/\npicture.JPG; буфер хранения: picture.jpg)
  • сохраняет пространство шаблона в буфер хранения (пространство шаблона: dir/\npicture.JPG; буфер хранения: dir/\npicture.JPG)
  • удаляет перевод строки из пространства шаблона (пространство шаблона: dir/picture.JPG; буфер удержания: dir/\npicture.JPG)
  • печатает пространство шаблона (буферы без изменений)
  • обмен буфера удержания и пространства образца (пространство образца: dir/\npicture.JPG; буфер удержания: dir/picture.JPG)
  • удаляет перевод строки и то, что следует из пространства шаблона (пространство шаблона: dir/; буфер удержания: dir/picture.JPG)
  • сохраняет пространство шаблона в буфер хранения (пространство шаблона: dir/; буфер хранения: dir/)
1 голос
/ 18 апреля 2019

Если я правильно понимаю ваш вопрос, вы на самом деле ищете способ найти все файлы в этой папке и всех подпапках и получить полный путь к ним.Если это так, вы должны использовать find вместо ls.Например:

find .

или если вы хотите получить полный путь от root, вы можете сделать:

find /home/yourname/thedirectory/you/are/looking/in
...