假设我们有一系列文件,列为:
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列表中获取?
答案 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
中删除$file
。 sort -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