如果找到了模式,如何在bash中粘贴包含其他模式的最后一行之前呢?

时间:2019-04-18 07:47:27

标签: bash sed replace gsub

在使用命令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 *”的“之前的最后一行”,然后将:替换为{{1} }。 为了获得这一点:

/

我没有找到一种方法来解释bash包含“ / 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

任何帮助我完成这部分代码的建议都将受到赞赏。

4 个答案:

答案 0 :(得分:2)

虽然还有其他更好的方法来获取文件列表(如果不是一种选择),但是对于您的特定问题,如果编写一个简单的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 :(得分:1)

如果我正确理解您的问题,那么您实际上是在寻找一种方法来查找此文件夹和所有子文件夹中的所有文件,并获取它们的完整路径。如果是这种情况,则应使用find而不是ls。喜欢:

find .

或者如果您希望从根目录获取完整路径,则可以这样做:

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

答案 2 :(得分:1)

尽管被误导了,但可以使用sed

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

您可以here试试。

遇到目录时,将使用第一个表达式(基于该行以:结尾的事实),将其打印并在替换:后将目录路径保存在保持缓冲区中通过/路径分隔符。

第二个表达式是在遇到.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/

答案 3 :(得分:1)

如果您的数据位于“ d”文件中,请尝试使用gnu sed:

sed -E '/Sp_[0-9]+:$/{h;p;:c N;/\.JPG$/{s!:\n\s*!/!p;g;bc}; z}' d