【问题标题】:How to sort and print array listing of specific file type in shell如何在shell中排序和打印特定文件类型的数组列表
【发布时间】:2020-08-28 05:26:08
【问题描述】:

我正在尝试编写一个循环,我想用它来提取所有子目录中的文本文件名并将某些字符串附加到它。此外,我希望文本文件名按^ 之后的数字排序。

例如,我有三个子目录mydir1, mydir2, mydir3。我有, 在 mydir1 中,

file223^1.txt
file221^2.txt
file666^3.txt

在 mydir2 中,

file111^1.txt
file4^2.txt

在 mydir3 中,

file1^4.txt
file5^5.txt

预期结果final.csv

STRINGmydir1file223^1
STRINGmydir1file221^2
STRINGmydir1file666^3
STRINGmydir2file111^1
STRINGmydir2file4^2
STRINGmydir3file1^4
STRINGmydir3file5^5

这是我试过的代码:

for dir in my*/; do
  array=(${dir}/*.txt)
    IFS=$'\n' RGBASE=($(sort <<<"${array[@]}"));
    for RG in ${RGBASE[@]}; do
    RGTAG=$(basename ${RG/.txt//})
    echo "STRING${dir}${RGTAG}" >> final.csv
done
done

有人可以解释一下我的代码有什么问题吗?此外,可能还有其他更好的方法可以做到这一点,但我想使用 for 循环。

这段代码的输出:

$ cat final.csv
STRINGdir1file666^3.txt
STRINGdir2file4^2.txt
STRINGdir3file5^5.txt

【问题讨论】:

  • 通常使用findwhile 循环更方便。填充数组 bash 有mapfile 命令,与find 一起使用更可靠。
  • 到您的代码:以“IFS”开头的行不是您所期望的。删除IFS=$'\n' 或用mapfile -t RGBASE &lt; &lt;(sort &lt;&lt;&lt;"${array[@]}") 替换该行以打印所有行。但排序仍然不起作用。
  • 要更正排序,请使用此行RGBASE=($( printf "%s\n" "${array[@]}" | sort -t"^" -k2 ))。这告诉sort 对帽子后面的数字进行排序。

标签: linux bash shell


【解决方案1】:

作为适用于您的特殊情况的起点,我为此准备了两个班轮。

mapfile -t array < <( find my* -name "*.txt" -printf "STRING^^%H^^%f\n" | cut -d"." -f1 | LANG=C sort -t"^" -k3,3 -k6 )
printf "%s\n" "${array[@]//^^/}"

要限制目录深度,您可以添加-maxdepth 以及要搜索的子目录数。 find 命令还可以在搜索中使用正则表达式,适用于整个路径,可用于处理更复杂的目录树。

困难在于两个位置和分隔符的排序。 我的想法是添加一个分隔符,之后可以很容易地删除它。 sort 命令只能处理一个分隔符,因此我必须使用双帽子作为分隔符,可以在不删除文件名中的单帽子的情况下将其删除。

【讨论】:

    【解决方案2】:

    使用 decorate-sort-undecorate 习惯用法的解决方案可能是:

    printf "%s\n" my*/*.txt |
    sed -E 's_(.*)/(.*)\^([0-9]+).*_\1\t\3\tSTRING\1\2^\3_' |
    sort -t$'\t' -k1,1 -k2,2n |
    cut -f3
    

    假设文件名不包含制表符或换行符。


    基本解释:printf 将每个路径名打印在单独的行上。 sed 将路径名 dir/file^number.txt 转换为 dir\tnumber\tSTRINGdirfile^number\t 表示制表符)。目的是在sort 命令中使用制表符作为字段分隔符。 sort 按第一个(按字典顺序)和第二个字段(按数字)对行进行排序。 cut 丢弃第一个和第二个字段;剩下的字段就是我们想要的。

    【讨论】:

    • 这是一种非常有效的技术,但您可能需要向 OP 解释您正在使用 sed 临时将制表符添加到现有文件名,以简化和改进 sort 的排序使用选项卡字段分隔符。我怀疑提问者丢失了大部分内容。
    • @DavidC.Rankin 够公平的。添加了基本解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2019-05-14
    • 2016-10-25
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2017-12-15
    相关资源
    最近更新 更多