【问题标题】:Unix - how to merge filename inside content with cat and baseline?Unix - 如何将内容中的文件名与 cat 和基线合并?
【发布时间】:2019-05-11 14:36:49
【问题描述】:

我想合并文件(一行),文件名在行首。

'cat' 对文件进行合并,'basename -a' 提供文件鬃毛,但我不知道如何获得两者?

$ echo "content1" > f1.txt
$ echo "content2" > f2.txt
$ cat f*.txt > all.txt

$ cat all.txt
content1
content2

$ basename -a f*.txt
f1.txt
f2.txt

Would like this result :
$ cat all.txt
f1.txt  content1
f2.txt  content2

【问题讨论】:

    标签: unix cat


    【解决方案1】:

    只需使用grep -H。修改分隔符的后期处理:

    $ for i in 1 2; do echo content$i > f$i.txt; done
    $ grep -H . *.txt 
    f1.txt:content1
    f2.txt:content2
    $ grep -H . *.txt  | sed 's/:/  /'
    f1.txt  content1
    f2.txt  content2
    

    或者,

    $ awk '{printf "%s\t%s\n", FILENAME, $0}' *.txt
    f1.txt  content1
    f2.txt  content2
    

    【讨论】:

    • 请注意,我使用 sed 替换 : 而不是 tr 以避免在第一个冒号之后替换冒号,但这是一个非常没有意义的鲁棒性尝试,因为它将替换文件名中的第一个冒号(如果出现)。
    【解决方案2】:

    使用循环。遍历每个*.txt 文件,将其名称回显到输出文件而不使用换行符(使用echo -n,完成)将其内容附加到输出文件,最后附加一个换行符。请注意 >> 附加。使用> 会覆盖。

    rm -f all.txt *.txt 中的 f;做 echo -n "$f" >> all.txt; cat "$f" >> all.txt;回声>>所有.txt;完毕

    如果您的输入文件末尾已经包含换行符,那么您跳过最后的 echo 并执行以下操作:

    *.txt 中的 f;做 echo -n "$f" >> all.txt; cat "$f" >> all.txt;完毕

    如果您使用 tcsh 而不是 bash,那么您可以使用 foreach,但您不能在单个命令中编写整个循环。通常你会在脚本中写这个:

    foreach f (*.txt) echo -n "$f" >> all.txt 猫 "$f" >> all.txt 结尾

    要在单个命令行中获得此功能,您需要这样的东西:

    printf 'foreach f (*.txt)\n echo -n "$f" >> all.txt\n cat "$f" >> all.txt\n end' | tcsh

    【讨论】:

    • 不适用于 shell : $ for f in *.txt ;做 echo -n "$f" >> all.txt ; cat "$f" >> all.txt ;为:找不到命令。 f:未定义的变量。
    • @DenisfromValThorens 你用的是什么外壳?
    • macOS 上的终端。
    • 好吧,我的终端上的默认 shell 是 tcsh 。当我切换到 bash 时工作良好。 Tcsh 不支持循环......谢谢。
    • @DenisfromValThorens 也添加了 tcsh 版本。
    猜你喜欢
    • 1970-01-01
    • 2012-05-31
    • 2017-09-08
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2017-12-15
    相关资源
    最近更新 更多