約300個のファイルを含むフォルダがあります。
PD26414b.fixedheader.hs37d5.cram
PD26414b.fixedheader.hs37d5.cram.crai
PD26415g.fixedheader.hs37d5.cram
PD26415g.fixedheader.hs37d5.cram.crai
ファイル名のID(PD26414b、PD26415g)をテキストファイルに保存したのと同じ元の名前に変更したいと思います。
head names.homologs.txt
PD26414b SAMEA3471115
PD26415g SAMEA3471120
PD26433c SAMEA3471126
PD26429d SAMEA3471130
したがって、PD26414bの同族体名はSAMEA3471115です。
私が望むファイル名は
SAMEA3471115.fixedheader.hs37d5.cram
SAMEA3471115.fixedheader.hs37d5.cram.crai
SAMEA3471120.fixedheader.hs37d5.cram
SAMEA3471120.fixedheader.hs37d5.cram.crai
Linuxでこれを行う方法はありますか? sedとmvの組み合わせでなければならないことを知っていますが、正確なコマンドがわかりません。
答え1
名前変更ユーティリティがインストールされていない場合は、いつでも独自にロールアウトできますが、追加機能はありません。
perl -le 'local $/;
my %h = <STDIN> =~ /^(.*) (.*)$/mg;
rename $_, s/^[^.]+/$h{$&}/r
for @ARGV;
' *cram* < names.homologs.txt
Pearlの標準入力にあるソースファイルを使用して名前マップハッシュを初期化し、それを後続の名前変更コマンドに適用できます。
ファイル名に改行文字がないため、sedを使用してこれを実行できます。
sed -Ee '
1i\
h
s|\S+|s/^[.][/]&[.]/|
s||.\\/&./;ta|2
$a\
:a\
G\
s/(.*)\\n(.*)/\\2 \\1/
' names.homologs.txt > genMvPairs
find . -maxdepth 1 -type f -name '*.cram*' |
sed -Ef genMvPairs - | xargs -n2 -t mv -f
答え2
Linuxシステムを使用している場合、またはperl renameコマンド(オペレーティングシステムに応じて、またはと呼ばれる場合があります)にアクセスでき、IDにスペースやその他のスペースが含まれていないと仮定すると、次のことができrename
ますprename
。perl-rename
従業員:
while read id hom; do
rename -n "s/^$id/$hom/" "$id".*
done < names.homologs.txt
これは実行するジョブを印刷するだけで、実際に名前を変更することはありません。要件を満たしていることを確認したら、-n
実際に変更することを選択せずにもう一度実行してください。
または、シェルで次のことを実行できます。
while read id hom; do
for file in "$id".*; do
newFile=$(printf '%s\n' "$file" | sed "s/$id/$hom/")
mv -- "$file" "$newFile"
done
done < names.homologs.txt
ただし、これは名前の競合がなく(ファイルの新しい名前が既存のファイル名と一致する場合は既存のファイルを上書きします)、ファイル名に改行文字がないと仮定します(ファイルの新しい名前が既存のファイル名と一致します)。一時ファイルを使用する場合は、実際に安全でなければなりません。仮定)。
答え3
これは下半期に似ていることがわかりました。テドンの答えしかし、私はファイルの新しい名前を計算するためのより安全で迅速な方法を使用しています。
使用/bin/sh
:
#!/bin/sh
while read -r id homolog; do
for oldname in "$id".*; do
[ -e "$oldname" ] || continue
newname=$homolog.${oldname#$id.}
mv -- "$oldname" "$newname"
done
done <names.homologs.txt
これは、名前を変更したいファイルが現在のディレクトリにあると仮定します。スクリプトはファイルの各行から2つの文字列を読み取り、2つの変数names.homologs.txt
sumid
として読み込みますhomolog
。
それぞれに一致する名前を持つ現在のディレクトリのファイルをループしようid
とします。"$id".*
これらの各ファイルに存在する場合は、ユーティリティを使用して$id.
文字列の先頭にある部分を 。$homolog.
mv
名前の競合は解決されません。
答え4
bash
@terdonが言ったように、ファイル名に奇妙な文字がなく、多数の同族体がない純粋な解決策は次のとおりです。
#!/usr/bin/env bash
declare -a homologs
while read key val
do {
homologs["$key"]="$val"
} done < names.homologs.txt
while read file
do
# key is the part before the dot
key="${file%%.*}"
# end is part after the first dot to the end
end="${file#*.}"
printf 'mv -- "%s" "%s.%s"\n' "${file}" "${homologs["$key"]}" "$end"
done