2013-09-04 23 views
5

lsコマンドで出力される一連のファイルを、ABCDE1234A1789.RST.txtまたはのいずれかのパターンに一致するように数字列で並べ替えようとしています( '789'フィールド)。可変長のファイル名内でbash sortコマンドを使用する

上記の例のパターンでは、ABCDEはすべてのファイルで同じですが、1234または12345の数字は常に4桁または5桁の数字です。 A1はすべてのファイルで同じ長さですが、値が異なる可能性があるため、残念ながら区切り文字として使用することはできません。最初の.の後のすべてがすべてのファイルで同じです。ような何か:

ls -l *.RST.txt | sort -k +9.13 | awk '{print $9} ' > file-list.txt 

は私がソートするフィールドの前にあるため、文字の可変長の短いファイル名ではなく、長いものにマッチします。

短い長さのファイルを最初に埋め込んですべてのファイルを同じ長さにすることなく、すべてのファイルを並べ替える方法はありますか?

+1

FYI - 'sort'コマンドはbashの一部ではなく、標準のUNIXユーティリティです。したがって、どのプログラム(およびシェル)でも利用できます。 –

答えて

4

レスキューへのPerl!

perl -e 'print "$_\n" for sort { substr($a, -11, 3) cmp substr($b, -11, 3) } glob "*.RST.txt"' 

あなたのperlは(5.10以降)より最近のものである場合は、bashでこれを行うための従来の方法は、あなたのソートフィールドを抽出することである

perl -E 'say for sort { substr($a, -11, 3) cmp substr($b, -11, 3) } glob "*.RST.txt"' 
+0

ありがとうございました(そして、ありがとう、perl)。 5.10より前のバージョンを使用しているので、トップラインはこれに対して完全に機能します。 –

2

にそれを短縮することができます。 sortコマンドを除いて、次が単独で純粋なbashで実装されています(この質問が要求するように見えるよう)

sort_names_by_first_num() { 
    shopt -s extglob 
    for f; do 
    first_num="${f##+([^0-9])}"; 
    first_num=${first_num%[^0-9]*}; 
    [[ $first_num ]] && printf '%s\t%s\n' "$first_num" "$f" 
    done | sort -n | while IFS='' read -r name; do name=${name#*$'\t'}; printf '%s\n' "$name"; done 
} 

sort_names_by_first_num *.RST.txt 

、改行区切りのファイル名を言ったそれは悪い習慣です:UNIXファイルシステム上のファイル名はに許可されていますリスト内の改行で区切ることで、リストに有効な名前の範囲の実質的なサブセットを含めることができなくなります。あなたのリストをNULで区切る方が良い方法です。ので、あなたが変わらないと認識しているファイル名の部分から

sort_names_by_first_num() { 
    shopt -s extglob 
    for f; do 
    first_num="${f##+([^0-9])}"; 
    first_num=${first_num%[^0-9]*}; 
    [[ $first_num ]] && printf '%s\t%s\0' "$first_num" "$f" 
    done | sort -n -z | while IFS='' read -r -d '' name; do name=${name#*$'\t'}; printf '%s\0' "$name"; done 
} 

sort_names_by_first_num *.RST.txt 
+0

チャールズ、非常に包括的な代替案ありがとうございました。このユースケースでは、perlはユーザに利用可能であり、おそらくbash関数より実装するほうがわずかに簡単ですが、私はこのオプションに非常に感謝しています! –

3

、あなたが実際にソートが使用するキーを構築することができます:それはそうのようになりますやって、これは何

$ echo ABCDE{99999,8765,9876,345,654,23,21,2,3}A1789.RST.txt \ 
    | fmt -w1 \ 
    | sort -tE -k2,2n --debug 
ABCDE2A1789.RST.txt 
    _ 
___________________ 
ABCDE3A1789.RST.txt 
    _ 
___________________ 
ABCDE21A1789.RST.txt 
    __ 
etc. 

文字Eのフィールドを区切り、2番目のフィールドを数値で使用するように指示します。 --debugはcoreutils 8.6に入っており、どのような並べ替えが行われているかを正確に見るのに非常に役立ちます。

関連する問題