【问题标题】:How to combine a prefix to output of ls in bash?如何在bash中将前缀组合到ls的输出?
【发布时间】:2019-10-12 17:43:43
【问题描述】:

假设我在父目录中有一些图像:../imagea/a.png 和 ../images/b.png。

当我这样做时:

ls ../images

# I get
../images/a.png
../images/b.png

如何为所有这些输出添加前缀 ![]( 和后缀 )

我试过了:

!ls ../images/*.png | cat

# am not sure what to do next

需要的输出

![](../images/a.png)
![](../images/b.png)

感谢您的帮助。

【问题讨论】:

    标签: python bash shell jupyter-notebook markdown


    【解决方案1】:

    最简单的解决方案是使用标准 posix find 命令和 printf 操作,如下所示:

     find ../images -name "*.png" -printf '![](%p)\n'
    

    解释:

    ../images - 目标目录

    "*.png" - 全局模式

    -printf - 输出格式操作

    '![](%p)\n' - 输出完整路径名的格式参数。

    示例:

    $ ls -l
    total 8
    drwxrwxr-x.  3 cfrm cfrm   15 Dec 13  2018 app
    drwxrwxr-x.  2 cfrm cfrm   23 Mar 24  2019 app_5811_install
    drwxrwxr-x. 13 cfrm cfrm 4096 Dec 12  2018 app_58_install
    drwxrwxr-x.  2 cfrm cfrm 4096 Oct  3  2018 grants
    -rwx------.  1 cfrm cfrm  526 Feb 17  2019 ic_start_all.sh
    -rwx------.  1 cfrm cfrm  920 Oct  4  2018 ic_status_all.sh
    -rwx------.  1 cfrm cfrm  984 Sep 27  2018 ic_stop_all.sh
    -rwxrwxr-x.  1 cfrm cfrm 1693 Dec 13  2018 loadTrigger.sh
    
    
    
    $ find . -name "*.sh" -printf '![](%p)\n'
    ![](./ic_stop_all.sh)
    ![](./ic_status_all.sh)
    ![](./loadTrigger.sh)
    ![](./ic_start_all.sh)
    

    【讨论】:

      【解决方案2】:

      循环遍历 glob 模式,并打印所需格式的每一行:

      for filename in ../*.png; do echo '!'"[]($filename)"; done
      

      【讨论】:

      • 非常感谢,当我必须为图像创建降价链接时,它会有所帮助。但是当我的图像很少时,我想复制粘贴![](../images/) 并将ls ../images/*.png 的输出放入其中会更容易。但是,当我有很多图像时,for 循环很有用。
      【解决方案3】:

      首先,我不相信你。 ls ../images 只会输出基本名称,例如:

      a.png
      b.png
      ...etc...
      

      不同的 命令ls ../images/* 可以提供您显示的输出。

      虽然在使用来自 GNU coreutils 的 ls 的系统上,如 Linux,如果输出是终端并且文件名很短,就像你展示的那样,ls 没有选项会做多列输出更像:

      ../images/aaaaa.png   ../images/ddddd.png  ../images/ggggg.png
      ../images/b.png       ../images/eeeee.png  ../images/hhhhhh.png
      ../images/ccccc.png   ../images/f.png      ../images/iiiiii.png
      

      除非你有一个别名(或阴影函数或脚本)强制-1(一个)选项来防止这种情况。或者实际名称(显着)更长,因为它们可能应该是。 或者你正在管道到某个东西,甚至是cat,因为ls 的输出是管道而不是终端。这些细节很重要。

      在某些情况下 sed 和 awk 一样好,而且通常更简洁:

      ls | sed 's/^/![](/; s/$/)/'
      # sed processes a string of command(s) for each line read from stdin, 
      # and writes the result to stdout (by default, -n overrides this)
      # s/old/new/ is string replacement using regex (which can be complex)
      # ^ in old matches the beginning of the line
      # $ in old matches the end of the line
      
      # this assumes none of your filenames contains a newline character
      # which Unix permits, but is rarely done because it is quite confusing
      

      因为你喜欢 printf 它可以完成整个工作:

      printf '![](%s)\n' ../images/*
      # printf takes a format string containing any mixture of literal text 
      # (including backslash+letter escapes mostly the same as C et succ)
      # and conversion specifiers beginning with % which each interpolate one argument
      # it repeats the format as needed to handle all the arguments, so here 
      # with one c.s. it repeats the format once for each argument = filename
      
      # this 'works' even if a filename contains newline
      # (but I don't think the result will work correctly as markdown)
      

      【讨论】:

      【解决方案4】:

      请您尝试关注一下。

      awk 'BEGIN{for(i=1;i<ARGC;i++)print "![](..",ARGV[i]")"}' ../images/*.png
      

      输出如下(a,b,c....png 是我为测试目的创建的测试文件)。

      ![](.. ../images/a.png)
      ![](.. ../images/b.png)
      ![](.. ../images/c.png)
      ![](.. ../images/d.png)
      

      【讨论】:

      • 绝对不是!它太丑了。感谢您的选择!但是,我为您的努力 +1。
      • @MilkyWay001,你为什么觉得它丑?请告诉我原因。
      • 命令awk对我来说有点尴尬,而且涉及到很多打字,我更喜欢使用cat或printf并尽量避免awk。但仍然很高兴知道选项。没有冒犯的意思。我没有冒犯 awk 命令的开发者。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      相关资源
      最近更新 更多