在 UNIX 中为至少有一行的文件添加时间戳

Add time stamp to file which has at least one row in UNIX

我在 ${POWERCENTER_FILE_DIR} 位置有文件列表。 这些文件由行 header 和值组成。

MART_Apple.csv
MART_SAMSUNG.csv
MART_SONY.csv
MART_BlackBerry.csv

要求:

  1. select 仅那些至少有 1 行的文件。
  2. 为至少有 1 行的文件添加时间戳。

例如: 如果除 MART_BlackBerry.csv 之外的所有文件至少有一行,那么我的输出文件名应该是

MART_Apple_20170811112807.csv
MART_SAMSUNG_20170811112807.csv
MART_SONY_20170811112807.csv

目前已尝试的代码

#!/bin/ksh
infilename=${POWERCENTER_FILE_DIR}MART*.csv
echo File name is ${infilename}
if [ wc -l "$infilename"="0" ];
then
        RV=-1
        echo "input file name cannot be blank or *"
        exit $RV 
fi

current_timestamp=`date +%Y%m%d%H%M%S`
filename=`echo $infilename | cut -d"." -f1 `
sftpfilename=`echo $filename`_${current_timestamp}.csv

cp -p ${POWERCENTER_FILE_DIR}$infilename ${POWERCENTER_FILE_DIR}$sftpfilename

RV=$?
if [[ $RV -ne 0 ]];then
        echo Adding timestamp to ${POWERCENTER_FILE_DIR}$infilename failed ... Quitting
        echo Return Code $RV
        exit $RV
fi

遇到如下错误:

line 3: [: -l: binary operator expected
cp: target `MART_Apple_20170811121023.csv' is not a directory
failed ... Quitting
Return Code 1

坦率地说,我无法理解其中的错误,也不确定我是否做对了。 unix 初学者 scripting.Can 任何专家都可以指导我正确的方法。

简化的脚本类似于

#!/bin/bash 
# Note I'm using bash above, can't guarantee (but I hope) it would work in ksh too.
for file in ${POWERCENTER_FILE_DIR}/*.csv # Check Ref [1]
do
if [ "$( wc -l "$file" | grep -Eo '^[[:digit:]]+' )" -ne 0 ] # checking at least one row? Check Ref [2]
then
 mv "$file" "${file%.csv}$(date +'%Y%m%d%H%M%S').csv" # Check Ref [3]
fi
done

参考资料

File Globbing [1]
Command Substitution [2]
Parameter Substitution [3]

这是一个仅使用 findshmvbasenamedate 的示例:

find ${POWERCENTER_FILE_DIR}MART*.csv ! -empty -execdir sh -c "mv {} $(basename -s .csv {})_$(date +%Y%m%d%H%M%S).csv" \;

我建议阅读 Unix Power Tools 以获得更多想法。

当谈到 shell 脚本时,很少有 single/one/correct 方法来完成所需的任务。

通常您可能需要在可读性、可维护性、性能、遵守某些本地编码标准与 shell-环境可用性之间进行权衡(我确信有更多的权衡)。所以,fwiw ...


根据您的要求,即您只对至少 1 行的文件感兴趣,我认为这也意味着您只对大小 > 0 的文件感兴趣。

一个简单的 ksh 脚本:

#!/bin/ksh

# define list of files
filelist=${POWERCENTER_FILE_DIR}/MART*.csv

# grab current datetime stamp
dtstamp=`date +%Y%m%d%H%M%S`

# for each file in our list ...
for file in ${filelist}
do
    # each file should have ${POWERCENTER_FILE_DIR} as a prefix;
    # uncomment 'echo' line for debugging purposes to display
    # the contents of the ${file} variable:
    #echo "file=${file}"

    #   '-s <file>' => file exists and size is greater than 0
    # '! -s <file>' => file doesn't exist or size is equal to 0, eg, file is empty in our case
    #
    # if the file is empty, skip/continue to next file in loop
    if [ ! -s ${file} ]
    then
        continue
    fi

    # otherwise strip off the '.csv'
    filebase=${file%.csv}

    # copy our current file to a new file containing the datetime stamp;
    # keep in mind that each ${file} already contains the contents of the
    # ${POWERCENTER_FILE_DIR} variable as a prefix; uncomment 'echo' line
    # for debug purposes to see what the cp command looks like:

    #echo "cp command=cp ${file} ${filebase}.${dtstamp}.csv"
    cp ${file} ${filebase}.${dtstamp}.csv
done

一些学习 ksh 的好资源: