Bash:列出不同的文件前缀

时间:2015-04-01 13:31:42

标签: regex bash

假设我们有一系列文件,列为:

T001_000.txt
T001_001.txt
T001_002.txt
T005_000.txt
T005_001.txt
T012_000.txt
...
T100_000.txt

我们想要将文件合并到同一个T ???字首。例如,我们想要执行前缀为T001的每个文件:

merge T001_*.txt > newT001.txt #i just made up this function

如何从不同前缀的bash列表中获取?

5 个答案:

答案 0 :(得分:2)

此脚本将从所有源文件中提取前缀(以T开头)并将它们合并到较小的“newT ????。txt”文件集中。

for file in T*.txt; do
        out="${file%_*}"
        cat $file >> new$out.txt
done;

答案 1 :(得分:2)

这是获得前缀的纯BASH方式:

for file in *.txt
do
     echo "${file%_*.txt}"
done | sort -u

这将为您提供所有文件前缀的列表。从那里,你可以用它来做你的猫。

for循环遍历所有文件。您可以说for file in T*_*.txt来限制您正在接收的文件。

${file%_*.txt}是一个小型右图案过滤器,用于从变量_*.txt中删除$filesort -u对所有这些前缀进行排序,并组合重复项。

最好的方法是将其用作函数:

function prefix
{
    for file in *.txt
    do
        echo "${file%_.txt}"
    done | sort -u
}

prefix | while read prefix
do
   ${prefix}_*.txt > cat $prefix.txt
done

请注意名称周围的${...}。那是因为$prefix_也是一个有效的shell脚本变量。我需要${prefix}让shell知道我在谈论$prefix而不是$prefix_

答案 2 :(得分:0)

假设你真的希望将所有类似前缀的文件一个接一个地捕获,并且你的前缀是文件名中_之前的所有位,那么这应该做你想要的。

awk '
    # When we are looking at the first line in a new file.
    FNR==1{
        # Find the index of the '_' character.
        ind=index(FILENAME, "_")
        # Construct the appropriate new filename.
        name="new" substr(FILENAME, 1, ind-1) ".txt"
    }
    {
        # Print the current line to the current filename.
        print > name
    }
' T*.txt

答案 3 :(得分:0)

下面的脚本会创建您描述的场景并解决它:

#! /bin/bash

# The code below generates the scenario you described
mkdir /tmp/test
cd /tmp/test
seq 1 10 | xargs printf "%.3d\n" |\
    while read x; do 
        seq 1 10 | xargs printf "%.3d\n" |\
        while read y; do 
            echo $x $y > T${x}_${y}.txt
        done 
    done


# The code below solves you problem

# Line below will create a list with unique prefixes
ls | grep -Po '^T\d+' | sort -u  |\
    while read prefix; do 
        # then for each prefix we merge those files
        ls | grep "^${prefix}_"| xargs  cat > comb_${prefix}.txt  
    done

结果你应该有10个comb_ {prefix} .txt文件,它们看起来像:

tiago@dell:~$ cat /tmp/test/comb_T008.txt 
008 001
008 002
008 003
008 004
008 005
008 006
008 007
008 008
008 009
008 010

答案 4 :(得分:0)

如果你真的只想要前缀,你可以非常快速地使用bash 4关联数组来唯一 - ify:

declare -A f
for x in *; do f[${x%%_*}]=1; done
printf 'Found %d prefixes\n' "${#f[@]}"

这是一个可以最大限度减少外部呼叫数量的解决方案。

shopt -s nullglob # Do not expand globs that match no files
for pat in T{0..9}{0..9}{0..9}; do
    files=( "$pat"_*.txt )
    if (( ${#files[@]} )); then
        cat "$pat"_*.txt > "${pat}_combined.txt"
    fi
done