【问题标题】:How to cat multiple files from a list of files in Bash?如何从 Bash 中的文件列表中分类多个文件?
【发布时间】:2012-07-22 02:24:18
【问题描述】:

我有一个包含文件列表的文本文件。我想cat他们的内容一起。做这个的最好方式是什么?我正在做这样的事情,但它似乎过于复杂:

let count=0
while read -r LINE
do
    [[ "$line" =~ ^#.*$ ]] && continue
    if [ $count -ne 0 ] ; then
        file="$LINE"
        while read PLINE
        do
            echo $PLINE | cat - myfilejs > /tmp/out && mv /tmp/out myfile.js
        done < $file
    fi
    let count++
done < tmp

我跳过了注释行并遇到了问题。必须有更好的方法来做到这一点,没有两个循环。谢谢!

【问题讨论】:

    标签: file bash loops


    【解决方案1】:

    或者在一个简单的命令中

    cat $(grep -v '^#' files) > output
    

    【讨论】:

    • @CharlesDuffy 我怀疑对于这个特定的应用程序是否真的会使用空格分隔的文件名。而是提出改进,因为在我看来,oneliner 是比 8 行脚本更好的解决方案。你真的在使用带有空格的文件名吗?
    • @Bernhard 不要误会,但当然我们总是处理带有空格的文件名。我们支持不知道区别的用户,如果编写一个可以处理它的脚本很容易,他们为什么要这样做?
    • 如果没有 cmets:cat $(cat files) &gt; output
    【解决方案2】:

    xargs cat &lt; files

    xargs 相对于$(cat) 的优势在于,cat 扩展为一个巨大的参数列表,如果由于 Linux 的最大命令行长度而在列表中有很多文件,这些参数可能会失败。

    不关心#的例子:

    printf 'a\nb\nc\n' > files
    printf '12\n3\n' > a
    printf '4\n56\n' > b
    printf  '8\n9\n' > c
    xargs cat < files
    

    输出:

    12
    3
    4
    56
    8
    9
    

    根据 OP 的要求忽略 # 的更具体示例:

    printf 'a\nb\n#c\n' > files
    printf '12\n3\n' > a
    printf '4\n56\n' > b
    printf  '8\n9\n' > c
    grep -v '^#' files | xargs cat
    

    输出:

    12
    3
    4
    56
    

    相关:How to pipe list of files returned by find command to cat to view all the files

    【讨论】:

      【解决方案3】:
      #!/bin/bash
      
      files=()
      while read; do
          case "$REPLY" in
              \#*|'') continue;;
              *) files+=( "$REPLY" );;
          esac
      done < input
      cat "${files[@]}"
      

      这种方法的优点在于:

      1. 唯一的外部命令cat 只执行一次。
      2. 为任何给定的行/文件名保留重要的空白是非常小心的。

      【讨论】:

      • 对比这个答案:cat $(grep -v '^#' files) > output 有什么明显的优势吗?
      • @user1470511 是的,如果任何文件名中包含空格,grep 答案可能会中断。
      【解决方案4】:
      {
        while read file
        do
          #process comments here with continue
          cat "$file"
        done
      } < tmp > newfile
      

      【讨论】:

      • 我修正了变量file的使用。牙套真的有必要吗?
      • @chepner:不,因为变量的使用是明确的。
      【解决方案5】:

      cat $(cat listoffiles) | grep -v "^#"怎么样?

      【讨论】:

      • 你不是说cat $(grep -v '^#' listoffiles)吗?空格问题呢?
      • OK,只要文件名不包含空格。
      • @chepner 或者只要 listoffiles 中的空格被转义,或者引用的名称。
      【解决方案6】:

      我最终得到了这个:

      sed '/^$/d;/^#/d;s/^/cat "/;s/$/";/' files | sh > output
      

      步骤:

      1. sed文件中删除空白行和注释掉的行。

      2. sed 然后将每一行包装在 cat ""; 中。

      3. 然后将脚本通过管道传送到 shoutput

      【讨论】:

      • 我忘了提到,这通过将文件名括在引号中来粗略地处理空格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      相关资源
      最近更新 更多