Bash: 重命名文件名的开头
Bash: rename beginning of filename
我有几个文件,如下所示:
1_150901_AC7GLHANXX_P2258_101_1.fastq.gz
1_150901_AC7GLHANXX_P2258_101_2.fastq.gz
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz
2_150901_AC7GLHANXX_P2258_101_2.fastq.gz
...即有两个文件以 1_
开头并以 _1.fastq.gz
或 _2.fastq.gz
结尾,两个文件以 [=19 开头也是如此=].我要做的是cat
以_1.fastq.gz
结尾的两个文件,像这样:
cat 1_150901_AC7GLHANXX_P2258_101_1.fastq.gz \
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz \
> 150901_AC7GLHANXX_P2258_101_1.fastq.gz
... 以便它们被合并并删除它们的前缀。我在比这更多的文件夹中有更多的文件,所以我想自动化它。我尝试了以下代码,但无济于事:
for f in *_*_1.fastq.gz
do
cat $f "${f/^1_/2_}" > "${f/^1_/}"
done
我认为我不太了解这种替换方法,但这是我过去用于不太复杂的文件名的方法(当它们只有不同的后缀,没有前缀时)。我认为开头的 ^
表示文件名的开头,但它似乎不像我想要的那样工作,所以很明显我做错了什么。我尝试进行一些故障排除:
for f in *_*_1.fastq.gz
do
echo "${f/^1_/}"
done
...给我...
1_150901_AC7GLHANXX_P2258_101_1.fastq.gz
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz
...这不是我想的那样。有人知道我该怎么做吗?
[编辑,澄清非重复问题]
这个问题和我之前的问题不同的是,我还有一个文件名前缀,而且这个前缀也存在于文件名的中间。另一个问题有一个更简单的情况,其中只有一个后缀需要重命名。
找到“1"s then check for the "2”
如果两者都cat在一起,删除部分。
for f in 1_*_1.fastq.gz
do
g="2_${f#1_}"
if [ -f "$g" ]
then
cat "$f" "$g" > "${f#1_}" && rm "$f" "$g"
fi
done
如果我处于你的位置,假设目录中只有这种格式的文件,我会采用这样的过程:
$ ls | cut -b3- | sort -u | tee stems.lst # list the stems
$ while read stem; do cat *_$stem > $stem; done <stems.lst
在你上线之前在测试目录中尝试这个,否则你会弄乱文件名并且恢复起来会很痛苦。
结束语:
- 技巧:由于重定向,这里有点不方便,但是通过 运行 某种形式的
echo "cat *_$stem > $stem"
在用真实的东西替换它之前。
- 之后别忘了删除
stem.lst
- 如果它稳定并且您需要重复,您可以将词干列表直接从
sort -u
传输到 while
- (如果这个问题对处于相同情况的其他人有用)如果你的文件名包含任何奇怪的东西,请在
while
行 的任何地方用双引号引起来 $stem
我有几个文件,如下所示:
1_150901_AC7GLHANXX_P2258_101_1.fastq.gz
1_150901_AC7GLHANXX_P2258_101_2.fastq.gz
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz
2_150901_AC7GLHANXX_P2258_101_2.fastq.gz
...即有两个文件以 1_
开头并以 _1.fastq.gz
或 _2.fastq.gz
结尾,两个文件以 [=19 开头也是如此=].我要做的是cat
以_1.fastq.gz
结尾的两个文件,像这样:
cat 1_150901_AC7GLHANXX_P2258_101_1.fastq.gz \
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz \
> 150901_AC7GLHANXX_P2258_101_1.fastq.gz
... 以便它们被合并并删除它们的前缀。我在比这更多的文件夹中有更多的文件,所以我想自动化它。我尝试了以下代码,但无济于事:
for f in *_*_1.fastq.gz
do
cat $f "${f/^1_/2_}" > "${f/^1_/}"
done
我认为我不太了解这种替换方法,但这是我过去用于不太复杂的文件名的方法(当它们只有不同的后缀,没有前缀时)。我认为开头的 ^
表示文件名的开头,但它似乎不像我想要的那样工作,所以很明显我做错了什么。我尝试进行一些故障排除:
for f in *_*_1.fastq.gz
do
echo "${f/^1_/}"
done
...给我...
1_150901_AC7GLHANXX_P2258_101_1.fastq.gz
2_150901_AC7GLHANXX_P2258_101_1.fastq.gz
...这不是我想的那样。有人知道我该怎么做吗?
[编辑,澄清非重复问题]
这个问题和我之前的问题不同的是,我还有一个文件名前缀,而且这个前缀也存在于文件名的中间。另一个问题有一个更简单的情况,其中只有一个后缀需要重命名。
找到“1"s then check for the "2” 如果两者都cat在一起,删除部分。
for f in 1_*_1.fastq.gz
do
g="2_${f#1_}"
if [ -f "$g" ]
then
cat "$f" "$g" > "${f#1_}" && rm "$f" "$g"
fi
done
如果我处于你的位置,假设目录中只有这种格式的文件,我会采用这样的过程:
$ ls | cut -b3- | sort -u | tee stems.lst # list the stems
$ while read stem; do cat *_$stem > $stem; done <stems.lst
在你上线之前在测试目录中尝试这个,否则你会弄乱文件名并且恢复起来会很痛苦。
结束语:
- 技巧:由于重定向,这里有点不方便,但是通过 运行 某种形式的
echo "cat *_$stem > $stem"
在用真实的东西替换它之前。 - 之后别忘了删除
stem.lst
- 如果它稳定并且您需要重复,您可以将词干列表直接从
sort -u
传输到while
- (如果这个问题对处于相同情况的其他人有用)如果你的文件名包含任何奇怪的东西,请在
while
行 的任何地方用双引号引起来
$stem