根据unix中的位置和分隔符获取子字符串

时间:2016-06-07 12:28:17

标签: unix

我有一些路径中的文件。当我做ls -lrt时,我知道

20160401_RM_ARN_MAPPING-M_RTL_NORTH_DELH_101.csv
20160401_RM_ARN_MAPPING-M_RTL_NORTH_DELH_102.csv
20160401_RM_ARN_MAPPING-M_BND_NORTH_DELH_102.csv
20160405_RM_ARN_MAPPING-M_RTL_NORTH_DELH_101.csv
20160405_RM_ARN_MAPPING-M_RTL_NORTH_DELH_102.csv
20160401_MAP_RTL_BANK-M_RTL_NORTH_DELH_101.csv
20150401_RM_ARN_MAPPING-M_RTL_NORTH_DELH_101.csv

我希望在日期之后和“ - ”分隔符之前使用不同的文件名。

我试过

ls -lrt | awk '{print $9}' | sed '1d' | awk -F'-' '{print $1}'

它给出了

20160401_RM_ARN_MAPPING
20160401_RM_ARN_MAPPING
20160401_RM_ARN_MAPPING
20160405_RM_ARN_MAPPING
20160405_RM_ARN_MAPPING
20160401_MAP_RTL_BANK
20150401_RM_ARN_MAPPING

但我只想要

RM_ARN_MAPPING 
MAP_RTL_BANK

作为输出,即删除日期后的不同名称。这里前8个字符是固定的,它将是YYYYMMDD格式。

4 个答案:

答案 0 :(得分:3)

Do not parse ls。相反,遍历目录中的元素keep track of the new names with an array。要获取干净的数据,请使用shell parameter expansion

for file in your_dir/*; do
   no_date=${file#*_}              # remove up to the first _
   no_dash=${no_date%%-*}          # remove from the first -
   [[ " ${var[@]} " =~ " ${no_dash} " ]] || var+=($no_dash)
done

然后,检查元素:

$ printf "%s\n" "${var[@]}"
RM_ARN_MAPPING
MAP_RTL_BANK

答案 1 :(得分:1)

添加cut -d '_' -f 2-

那是

ls -lrt | awk '{print $9}' | sed '1d' | awk -F'-' '{print $1}' | cut -d '_' -f 2-

2-意味着第二部分,一切都结束......

答案 2 :(得分:1)

这个答案可以避免解析ls输出 - 防止包含奇数字符的文件名 - 使用带有空字符记录分隔符输出的-lrt和补充stat安全地模拟sort\0也可以用作awk分隔符,我们可以将该工具用于文本操作的其余部分。使用正则表达式/^[^_]+_/处理前导数字和下划线的删除。删除重复的名字"通过关联数组查找完成。

stat --printf '%Y %n\0' *_*-*.csv |
    sort -nz |
    awk -v RS='\0' '{
            sub(/^[^_]+_/, "")
            sub(/-.*$/, "")
            if ($0 in y)
                next
            y[$0]=1
            print
    }'

答案 3 :(得分:0)

可以这样做: -

ls -ltr|sed 1d|awk '{print $9}'|cut -d"-" -f1  |cut -d_ -f2-|sort|uniq

<强>解释

ls -ltr - &gt;列表文件

sed 1d - &gt;先忽略

awk'{print $ 9}' - &gt;打印第9栏

其他我猜是自我解释