如果找到一个模式,如何粘贴之前的最后一行包含bash中的另一个模式?

问题描述 投票:1回答:4

在使用命令list.txtls -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

我没有找到一种解释方法来解释“之前的最后一行”包含“/ So *”。这是我的代码:

 # 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

任何建议,以帮助我完成这部分代码非常感谢。

bash sed replace gsub
4个回答
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
投票

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

find .

或者如果你想从root获取完整路径,你可以这样做:

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

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/

1
投票

如果你的数据在'd'文件中,请尝试gnu sed:

sed -E '/Sp_[0-9]+:$/{h;p;:c N;/\.JPG$/{s!:\n\s*!/!p;g;bc}; z}' d
© www.soinside.com 2019 - 2024. All rights reserved.