1

最後に発生した後の番号でファイル名を並べ替えたいのですがs、どうすればよいですか?

例えば:

01002M00T1relaxouspios1001a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxos201a001.nii
01002M00T1relaxouspios901a001.nii

ソートされたファイル名は次のようになります。

01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii

使ってみました

$sort -ts -nk2,4

ただし、最初の2つのファイル名に対してのみ機能します。

例2:

01002M00T1relaxos201a001.nii 
01002M00T1relaxouspios1001a001.nii 
01002M00T130relaxos301a001.nii 
01002M00T130relaxouspios901a001.ni

期待される出力:

01002M00T1relaxos201a001.nii 
01002M00T130relaxos301a001.nii 
01002M00T130relaxouspios901a001.ni
01002M00T1relaxouspios1001a001.nii 
4

3 に答える 3

2

PerlやPythonのようなプログラミング言語を使用して、並べ替えたいものをもう少し指定することができますが、BASHを主張する場合は、ちょっとしたトリックを採用する必要があります。

を使用して並べ替えキーを作成し、作成した並べ替えキーsedに基づいて並べ替えてから、 `sed:を使用してそのキーを削除できます。

ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2)

上記は、正規表現の貪欲な力を使用して、必要なものを取得します。は\(.*s\)すべてを最後の小文字に一致させますs。は\(.*\)すべてに一致しますs。とは、グループでキャプチャされたさまざまなセクションと一致し\1ます。したがって、2つの文字列があります。1つ目はファイルの名前、2つ目は並べ替え文字列です。出力は次のようになります。\2\(...\)

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/'
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii

今、私は:の後の部分でソートすることができます^

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii

今、私がしなければならないのは、そのソートキーを削除することだけです。

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2| sed 's/ ^ .*//'
01002M00T1relaxouspios1001a001.nii
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
于 2012-11-30T14:52:36.363 に答える
2

数値が一意であり、インデックスとして十分な場合、エレガントなbash のみのソリューションがあります。アイデアは使用することですが、使用することではありません:bash arrayassociative

unset sortedlist
declare -a sortedlist
while read filename;do
    [[ $filename =~ s([0-9]+)[a-rt-z][^s]*$ ]] &&
       sortedlist[${BASH_REMATCH[1]}]=$filename
  done < <(ls)
printf "%s\n" "${sortedlist[@]}"
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii

注:配列では、フィールドは番号順にソートされるため、1001は よりも大きくなり901ます。

注意 2:[[ ... =~ ... ]]条件として、正規表現に一致しないファイル名は単純に無視されます。

于 2012-11-30T15:32:48.630 に答える
2

簡単に、次の-Vオプションを使用してバージョンの並べ替えを行います。

$ sort -V file

01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii

2番目の例が投稿された後に編集してください。

一般的なケース:

$ ls | awk -Fs '{print $NF, $0}' | sort -n | awk '{print $2}'

01002M00T1relaxos201a001.nii
01002M00T130relaxos301a001.nii
01002M00T130relaxouspios901a001.ni
01002M00T1relaxouspios1001a001.nii
于 2012-11-30T12:47:25.943 に答える