【问题标题】:If found a pattern, how to paste the last line before that contain another pattern in bash?如果找到一个模式,如何在 bash 中粘贴包含另一个模式的最后一行?
【发布时间】:2019-09-08 12:23:20
【问题描述】:

使用命令ls -R 将所有文件夹和子文件夹的列表放入list.txt 后,我有这种数据:

 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

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

【问题讨论】:

  • 为什么不直接找到Sp文件夹中的所有.jpg文件并输出列表?

标签: bash sed replace gsub


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    虽然被误导了,但sed 是可能的:

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

    你可以试试here

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

    当遇到.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】:

      虽然有更好的替代方法来获取文件列表,但如果这不是一个选项,那么对于您的具体问题,是否可以编写一个简单的 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
      

      【讨论】:

        【解决方案4】:

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

        find .
        

        或者如果您确实想要从根目录获取完整路径,您可以这样做:

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

        【讨论】:

        • 您可以使用$(pwd) 作为第二个示例。并且 OP 正在根据我的理解专门寻找 .JPG,所以你可能想添加一个 -name '*.JPG' 谓词
        • 是的,如果您正在查看当前目录,但您也可以指定任意路径。您甚至可以使用通配符或任何其他由您的 shell 扩展的东西。比如说,所有以p开头的用户:find /home/p*
        猜你喜欢
        • 1970-01-01
        • 2020-12-27
        • 2022-01-11
        • 1970-01-01
        • 2020-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多