在bash中提取文件名的一部分

时间:2014-12-29 14:36:04

标签: linux string bash shell

我有一个文件夹,其中包含大量具有模式的文件,这是一些字符串,后跟日期和时间:

BOS_CRM_SUS_20130101_10-00-10.csv (3 strings before date)
SEL_DMD_20141224_10-00-11.csv (2 strings before date)
SEL_DMD_SOUS_20141224_10-00-10.csv (3 strings before date)

我想遍历文件夹并在日期之前仅提取部分并输出到文件中。

Output
BOS_CRM_SUS_
SEL_DMD_
SEL_DMD_SOUS_

这是我的脚本,但它无效

#!/bin/bash

# script variables
FOLDER=/app/list/l088app5304d1/socles/Data/LEMREC/infa_shared/Shell/Check_Header_T24/

LOG_FILE=/app/list/l088app5304d1/socles/Data/LEMREC/infa_shared/Shell/Check_Header_T24/log

echo "Starting the programme at:  $(date)" >> $LOG_FILE

# Getting part of the file name from FOLDER
for file in `ls $FOLDER/*.csv`
do
    mv "${file}" "${file/date +%Y%m%d HH:MM:SS}" 2>&1 | tee -a $LOG_FILE
done #> $LOG_FILE

5 个答案:

答案 0 :(得分:3)

假设你在第一部分没有数字,你可以使用:

$ for i in *csv;do  str=$(echo $i|sed -r 's/[0-9]+.*//'); echo $str; done
BOS_CRM_SUS_
SEL_DMD_
SEL_DMD_SOUS_

parameter substitution

$ for i in *csv;do echo ${i%_*_*}_; done
BOS_CRM_SUS_
SEL_DMD_
SEL_DMD_SOUS_

答案 1 :(得分:3)

使用${var/pattern/replace}时,pattern必须是文件名glob,而不是执行命令。

使用模式删除运算符

,而不是使用替换运算符
mv "${file}" "${file%_*-*-*.csv}.csv"

%在变量末尾找到模式的最短匹配,因此该模式将匹配文件名的日期和时间部分。

答案 2 :(得分:2)

使用sed扩展正则表达式和组来实现此目的。

cat filelist | sed -r 's/(.*)[0-9]{8}_[0-9][0-9]-[0-9][0-9].[0-9][0-9].csv/\1/'

其中filelist是一个包含您关注的所有名称的文件。当然,这只是一个占位符,因为我不知道你将如何列出所有符合条件的文件。例如,如果一个glob会做,你可以做

ls mydir/*.csv | sed -r 's/(.*)[0-9]{8}_[0-9][0-9]-[0-9][0-9].[0-9][0-9].csv/\1/'

答案 3 :(得分:2)

替换:

"${file/date +%Y%m%d HH:MM:SS}"

不太可能做任何事情,因为它不会执行date +%Y%m%d HH:MM:SS。它只是将其视为一种搜索模式,并且它不会被发现。

但是,如果您确实执行了该命令,那么您将获得当前日期和时间,这显然也不是您在文件名中找到的日期和时间。

如果该模式是精确的,那么您可以执行以下操作:

echo "${file%????????_??-??-??.csv}" >> "$LOG_FILE"

答案 4 :(得分:1)

使用grep

ls *.csv | grep -Po "\K^([A-Za-z]+_)+"

输出:

BOS_CRM_SUS_
SEL_DMD_
SEL_DMD_SOUS_