【问题标题】:cat files with filenames in .tsv.tsv 中文件名的 cat 文件
【发布时间】:2014-09-16 06:57:56
【问题描述】:

我在制表符分隔的文件中提供了文件名。

例如:

file1 file2 file3
file4 file5
file6 file7 file8 file9 file10
file11 file12

......等等。

我需要能够做到:

cat file1 file2 file3 > newfile1
cat file4 file5 > newfile2
cat file5 file7 file8 file9 file10 > newfile3

.....

此文件共有 140 行,每行有多个文件名。在每一行中,我需要连接文件。每个文件名都有一个 uniq 名称,因此我需要为新文件命名不同的名称。

我想用来重命名的每个文件前缀中都有前导字符。例如,(file1) A1-2_B1.txt 和 (file2) A1-4_B1.txt 将连接到文件 A1_B1.txt

有什么建议吗?感谢所有帮助。

我知道我可以使用

 (cat inputs.txt | -n 140 cat) >> newfile.txt  

使用每行都有文件名的文件来创建一个新文件。但是,我在处理每行多个文件时遇到了麻烦,无法制作多个新文件。

我想知道我是否将所有输出文件名放入一个文本文件中,例如:

A1_B2.txt
A2_B3.txt
..etc...

并使用类似的东西:

 (cat inputs.txt | cat) >> (cat outputs.txt)

如果它会工作。

【问题讨论】:

  • 让我们知道您到目前为止所尝试的所有内容也将不胜感激。
  • @Technext。查看修改。
  • @jm666。你能详细说明一下吗?

标签: bash text-files filenames cat


【解决方案1】:

使用awk将文件转换为脚本,然后通过管道进入shell执行:

awk '{print "cat", $0, ">", "newfile" ++c}' inputs.txt | sh

如果您有一个“输出名称”文件与 输入文件,然后

awk '{getline out < "outputs.txt"; print "cat", $0, ">", out}' inputs.txt | sh

chepner 的 bash 解决方案的另一种方法:

paste outputs.txt inputs.txt | while IFS=$'\t' read -a line; do
    cat "${line[@]:1}" > "${line[0]}"
done

【讨论】:

    【解决方案2】:
    i=0
    while IFS=$'\t' read -a names; do
        cat "${names[@]}" > "newfile$((++i))"
    done < inputs.txt
    

    应该可以解决问题。每一行都被读入一个数组,该数组的内容被用作cat的参数列表。

    如果您有一个包含输出名称的单独文件:

    while IFS=$'\t' read -a names;
          read output <&3; do
        cat "${names[@]}" > "$output"
    done < inputs.txt 3< outputs.txt
    

    【讨论】:

    • 有没有办法用你的脚本为新文件提供一个附加文件的名称?
    • 我也只得到一个输出文件。输入中列出的最后一行中的那个。
    • 奇怪;单个输出文件的名称是什么?
    • newfile1 就是全部。输入的最后一行。
    • 你确定你有i=0 before循环,而不是循环内?
    【解决方案3】:

    因此,使用 chepner 和 glenn jackman 的答案,我能够制作一个脚本来获得我所需要的。使用 glenn jackman 的 chepners 版本,我能够重命名给定 output.txt 的文件,然后我轻松地修改了 chepners 的原始文件,以从输入文件中删除那些在制作新文件后不再需要的文件。

    这是两者的结合:

    #!/usr/bin/bash
    
    echo "Getting inputs and output file names:"
    
    paste $1 $2 | while IFS=$'\t' read -a line; do
            cat "${line[@]:1}" > "${line[0]}"
    done
    
    wait
    
    echo "Removing old files"
    
    while IFS=$'\t' read -a names; do
            rm "${names[@]}"
    done < $2
    

    ~

    【讨论】:

    • 要删除旧文件,只需在第一个循环中添加rm "${line[@]:1}"
    • 这是有道理的。谢谢。你可以评论和编辑你的答案吗?我会删除我的..
    • 不,留下这个:删除文件不是您的问题的要求。
    【解决方案4】:

    经过许多不同的解决方案,另一个基于perl

    perl -nle 'system qq{cat $_ > out$.}' < input.txt
    

    (有效,如果文件名不包含空格)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      相关资源
      最近更新 更多