将类似的文件名用逗号隔开,将不同的文件名用空格隔开

时间:2019-05-09 14:23:20

标签: bash

我正在尝试从目录中的文件名中获取一个字符串,并以逗号分隔以及以单个空格分隔的不同文件名进行分组。请最后查看“预期输出”。

目录中的文件

usa_la2_sky_1.csv
usa_la2_sky_2.csv
usa_nyc1_sky_1.csv
usa_nyc1_sky_2.csv

我尝试过:

for f in *.csv ; do
    input=$input,$f
done
echo $input | sed s/,//

输出上面的代码:

usa_la2_sky_1.csv,usa_la2_sky_2.csv,usa_nyc1_sky_1.csv,usa_nyc1_sky_2.csv

预期输出:

usa_la2_sky_1.csv,usa_la2_sky_2.csv usa_nyc1_sky_1.csv,usa_nyc1_sky_2.csv

3 个答案:

答案 0 :(得分:1)

这可以做到:

ls *.csv | awk '{key=$0;sub(/_[^_]*csv/,"",key);a[key]=(key in a)?a[key]","$0:$0} 
        END{for (i in a){print a[i]}}' | 
    paste -s -d ' '

我们使用ls列出所有以.csv结尾的文件。然后,我们使用awk对文件进行分组。我们通过剥离每个_1.csv后缀来制作密钥。所有这些字符串都存储在数组中,并以“,”分隔。最后,我们将打印这些。由于您想按空格分隔组,因此我使用了粘贴-s。这会将每一行粘贴到由-d''表示的空格之间。

答案 1 :(得分:1)

尝试使用这种Shellcheck干净的纯Bash代码:

#! /bin/bash -p

shopt -s nullglob   # Globs that match nothing expand to nothing

input='' oldbase=''
for f in *.csv ; do
    base=${f%_*}
    [[ $base == "$oldbase" ]] && sep=, || sep=' '
    input+=${input:+$sep}$f
    oldbase=$base
done

printf '%s\n' "$input"
    如果在当前目录中没有CSV文件,
  • shopt -s nullglob会阻止代码尝试处理虚假的(文字的)*.csv文件。
  • base=${f%_*}$base设置为文件名,但不包括最后一个_字符。 (例如,$base的{​​{1}}是usa_la2_sky_1.csv。)请参阅Removing part of a string (BashFAQ/100 (How do I do string manipulation in bash?))
  • usa_la2_sky将当前文件名附加到当前input+=${input:+$sep}$f字符串中,并可能在前面加上分隔符。如果input为空,则${input:+$sep}扩展为空,否则扩展为$input的值。这样的效果是在$sep的开头没有分隔符。请参阅Parameter expansion [Bash Hackers Wiki]中的“使用替代值”部分。
    另一种选择是仅始终添加分隔符($input),然后再删除前导分隔符。删除前导分隔符的一种方法是input+=$sep$f

答案 2 :(得分:1)

您可以轻松地做到这一点,但是您需要知道last文件名是什么。您可以通过保存一个变量(最初设置为空)来处理。然后只需将每个文件名的起始部分与简单的参数扩展(符合POSIX)进行比较,例如

#!/bin/bash

last=                                       ## last originally empty
for i in *.csv; do                          ## loop over each file
    if [ -z "$last" ]; then                 ## if last empty, output file
        printf "%s" "$i"
    elif [ "$last" = "${i%_*}" ]; then      ## if last matches beginning of file
        printf ",%s" "$i"                   ## output comma and file
    else
        printf " %s" "$i"                   ## no match, output space and file
    fi
    last="${i%_*}"                          ## save beginning of filename in last
done
echo ""                                     ## tidy up with final newline

使用/输出示例

将文件放在示例目录中,例如

$ tree .
.
├── usa_la2_sky_1.csv
├── usa_la2_sky_2.csv
├── usa_nyc1_sky_1.csv
└── usa_nyc1_sky_2.csv

运行脚本会产生:

$ bash myscript
usa_la2_sky_1.csv,usa_la2_sky_2.csv usa_nyc1_sky_1.csv,usa_nyc1_sky_2.csv

在用逗号分隔的相似文件名中,用空格分隔的组(这是我的理解是您要的)。