【问题标题】:bash: process substitution, paste and echobash:进程替换、粘贴和回显
【发布时间】:2013-11-07 16:37:19
【问题描述】:

我正在尝试进程替换,这只是一个有趣的练习。

我想将字符串“XXX”附加到 'ls' 的所有值:

paste -d ' ' <(ls -1) <(echo "XXX")

这怎么行不通?不附加 XXX。但是,如果我想将文件名附加到自身,例如

paste -d ' ' <(ls -1) <(ls -1)

它有效。

我不明白这种行为。 echo 和 ls -1 都写入标准输出,但粘贴不读取 echo 的输出。

【问题讨论】:

  • echo 只产生一行; paste 需要为ls 生成的每一行提供一个字符串。

标签: bash unix stdout


【解决方案1】:

尝试这样做,使用printf hack 来显示具有零长度输出并附加 XXX 的文件。

paste -d ' ' <(ls -1) <(printf "%.0sXXX\n" *  )

演示:

$ ls -1
filename1
filename10
filename2
filename3
filename4
filename5
filename6
filename7
filename8
filename9

输出:

filename1 XXX
filename10 XXX
filename2 XXX
filename3 XXX
filename4 XXX
filename5 XXX
filename6 XXX
filename7 XXX
filename8 XXX
filename9 XXX

如果你只是想附加XXX,这个会更简单:

printf "%sXXX\n" 

【讨论】:

    【解决方案2】:

    如果你想在ls -l 输出的每一行之后输出XXX,你需要第二个命令输出x 倍的字符串。您只回显它一次,因此它只会附加到 ls 输出的第一行。

    如果你正在寻找一个小命令行来完成你可以使用sed的任务:

    ls -l | sed -n 's/\(^.*\)$/\1 XXX/p'
    

    【讨论】:

      【解决方案3】:

      还有一个有趣的,除了传说中的yes命令之外,没有使用任何外部命令!

      while read -u 4 head && read -u 5 tail ; do echo "$head $tail"; done 4< <(ls -1) 5< <(yes XXX)
      

      (我发布这个只是因为它很有趣,而且它实际上并不是 100% 偏离主题,因为它使用了文件描述符和进程替换)

      【讨论】:

        【解决方案4】:

        ...你必须:

        for i in $( ls -1 ); do echo "$i XXXX"; done
        

        永远不要使用for i in $(command)。详情请见this answer

        所以,要回答这个原始问题,你可以简单地使用这样的东西:

        for file in *; do echo "$file XXXX"; done
        

        使用 awk 的另一种解决方案:

        ls -1|awk '{print $0" XXXX"}'
        awk '{print $0" XXXX"}' <(ls -1) # with process substitution
        

        使用 sed 的另一种解决方案:

        ls -1|sed "s/\(.*\)/\1 XXXX/g"
        sed "s/\(.*\)/\1 XXXX/g" <(ls -1) # with process substitution
        

        和无用的解决方案,只是为了好玩:

        while read; do echo "$REPLY XXXX"; done <<< "$(ls -1)"
        ls -1|while read; do echo "$REPLY XXXX"; done
        

        【讨论】:

          【解决方案5】:

          它只对第一行执行此操作,因为它将参数 1 的第一行与参数 2 的第一行分组:

          paste -d ' ' <(ls -1) <(echo "XXX")
          

          ...输出:

          /dir/file-a XXXX
          /dir/file-b
          /dir/file-c
          

          ...你必须:

          for i in $( ls -1 ); do echo "$i XXXX"; done
          

          【讨论】:

          • 如果您想使用粘贴,您将需要一个初始化为“XXX”的元素数组,因为您列出的目录中存在文件。我认为在我上面的回答中使用 for 迭代要简单得多(甚至有些人可能会说不太优雅)。
          • 永远不要使用for i in $(command)更多细节请看这个答案:stackoverflow.com/questions/19606864/ffmpeg-in-a-bash-pipe/…
          【解决方案6】:

          你可以使用 xargs 来达到同样的效果:

          ls -1 | xargs -I{} echo {} XXX
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-05-28
            • 2018-04-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多