如何根据最后一个单词PATH中的前两个字符对文件进行排序

时间:2014-07-17 08:18:04

标签: linux bash sorting awk sed

请告知如何根据最后一个单词PATH中的前两个字符对文件进行排序(使用sort命令)

   /dir/dir/dir/LAST_WORD_PATH

示例:

如果以下PATH

      /Config/EMA/M5/Hatki Tekom/Customer Files/fSE-TMOLE.txt

所以最后一句话应该是

    fSE-TMOLE.txt

目标是对“最后一个字路径”中的前两个字符进行排序

然后两个第一个字符是(来自 fSE-TMOLE.txt

    fS

完整示例

排序前的

     /Config/EMA/M5/Cmo Buria Mobile/dzs Bulia Mole.txt
     /Config/EMA/M5/Hatki Tekom/Customer Files/fAE-TMOLE.txt
     /Config/EMA/M5/Cmo Buria Mobile/dos Bulia Mole.txt
     /Config/EMA/M5/Cmo Bgaia Mobile/Fustoer files/Backup/Cos Buia Mole-2.txt
     /Config/EMA/M5/VFONE Roia/Cbdne.ro.txt
     /Config/EMA/M5/TEKOM SRJA/IELOM SRJA.txt
     /Config/EMA/M5/VP Moe/Bobile.txt
排序后

     /Config/EMA/M5/VP Moe/Bobile.txt
     /Config/EMA/M5/VFONE Roia/Cbdne.ro.txt
     /Config/EMA/M5/Cmo Bgaia Mobile/Fustoer files/Backup/Cos Buia Mole-2.txt
     /Config/EMA/M5/Cmo Buria Mobile/dos Bulia Mole.txt
     /Config/EMA/M5/Cmo Buria Mobile/dzs Bulia Mole.txt
     /Config/EMA/M5/Hatki Tekom/Customer Files/fAE-TMOLE.txt
     /Config/EMA/M5/TEKOM SRJA/IELOM SRJA.txt

6 个答案:

答案 0 :(得分:2)

这是一种方式:

#!/bin/bash
while read f
do
   b=$(basename "$f")   # Get basic name of file without path
   b2=${b:0:2}          # Extract first 2 letters
   echo $b2:$f          # Output for awk to read with colon separator
done < file | sort -f | awk -F: '{print $2}'

答案 1 :(得分:1)

这个技巧使它成为:

$ awk 'BEGIN{FS="/"; OFS="|"} {print $NF, $0}' file | sort -fk1 | cut -d'|' -f2-
/Config/EMA/M5/VP Moe/Bobile.txt
/Config/EMA/M5/VFONE Roia/Cbdne.ro.txt
/Config/EMA/M5/Cmo Bgaia Mobile/Fustoer files/Backup/Cos Buia Mole-2.txt
/Config/EMA/M5/Cmo Buria Mobile/dos Bulia Mole.txt
/Config/EMA/M5/Cmo Buria Mobile/dzs Bulia Mole.txt
/Config/EMA/M5/Hatki Tekom/Customer Files/fAE-TMOLE.txt
/Config/EMA/M5/TEKOM SRJA/IELOM SRJA.txt

由于最后一个字段不是固定位置,我们将其复制到该行的前面,根据该字体进行排序,然后将其删除。

注意sort -f是忽略大小写,-k1根据第一列进行排序。

答案 2 :(得分:1)

使用perl

进行此操作的一种非常可靠的方法
#! /bin/bash 

input=/tmp/file
perl -F/ -anle '
    $F[$#F] =~ /^(..)/; 
    $key="\U$1"; 
    $h{$key}=[] unless exists $h{$key}; 
    push ${h{$key}},$_; 

    END{
        foreach $key (sort keys %h){
            foreach( @{$h{$key}}){
                print "$_"
            }
        }
    }' $input

<强>解释

它使用转换为大写字母的最后一个字段的前两个字符作为其键来创建哈希。哈希就像这样:

$VAR1 = {
          'IE' => [
                    '     /Config/EMA/M5/TEKOM SRJA/IELOM SRJA.txt'
                  ],
          'CO' => [
                    '     /Config/EMA/M5/Cmo Bgaia Mobile/Fustoer files/Backup/Cos Buia Mole-2.txt'
                  ],
          'DZ' => [
                    '     /Config/EMA/M5/Cmo Buria Mobile/dzs Bulia Mole.txt'
                  ],
          'CB' => [
                    '     /Config/EMA/M5/VFONE Roia/Cbdne.ro.txt'
                  ],
          'FA' => [
                    '     /Config/EMA/M5/Hatki Tekom/Customer Files/fAE-TMOLE.txt'
                  ],
          'DO' => [
                    '     /Config/EMA/M5/Cmo Buria Mobile/dos Bulia Mole.txt'
                  ],
          'BO' => [
                    '     /Config/EMA/M5/VP Moe/Bobile.txt'
                  ]
        };

然后我们根据键和打印值对哈希进行排序。

PS。此解决方案考虑了重复密钥的情况,因为它为每个密钥创建了一个数组。它应该比任何提供的解决方案都要快,因为它在perl中完成所有操作都没有shell分支。

答案 3 :(得分:0)

假设您的文件名不包含标签,您可以这样做:

cat files | sed s/.*/\&\\t\&/ | sed -r s/.*\\/\(..\).*\\t/\\1/ | sort | sed s/...//

/Config/EMA/M5/VP Moe/Bobile.txt
/Config/EMA/M5/VFONE Roia/Cbdne.ro.txt
/Config/EMA/M5/Cmo Bgaia Mobile/Fustoer files/Backup/Cos Buia Mole-2.txt
/Config/EMA/M5/Cmo Buria Mobile/dos Bulia Mole.txt
/Config/EMA/M5/Cmo Buria Mobile/dzs Bulia Mole.txt
/Eonfig/EMA/M5/Hatki Tekom/Customer Files/fAE-TMOLE.txt
/Config/EMA/M5/TEKOM SRJA/IELOM SRJA.txt

答案 4 :(得分:0)

您也可以使用此方法

sed  -r 's@^(/.*/)(.*)@\2|\1\2@g' filename | sort | sed -r 's/^[^|]+.(.*)/\1/g'

答案 5 :(得分:0)

这可能适合你(GNU sed and sort):

sed 's|.*/\(..\).*|\1&|' file | sort -sk1,1.2 | sed 's/..//'

提取“最后一个单词”的前2个字符并添加到每一行。使用稳定排序使用前置键保留位置进行排序。删除前置密钥。