如何在 Unix 脚本中剪切日期和时间

如何在 Unix 脚本中剪切日期和时间

我想问如何使用 cut 或其他类似命令来获取日期和时间...所以基本上$line是从以下位置检索的for loop

for line in $(cat $file);
do
   getdatetime=$(echo $line | cut -f4 -d,)
done

其中 的样本值为$line

883427446627317909,1114259,1573178423,2019-11-08 02:00:23,RD,4.7,0,351442429

该文件$file包含与示例类似的多行$line

的期望值为getdatetime

2019-11-08 02:00:23

但我只得到日期:

2019-11-08

是否有任何一行cut命令可以提取日期和时间?我需要保留 for 循环的结构。谢谢。

答案1

当您迭代未加引号的命令替换时$(cat $file),您将迭代所有cat $file单词可以是由空格(默认情况下为空格、制表符或换行符)分隔的任何内容。这意味着对于$file其中的一行

883427446627317909,1114259,1573178423,2019-11-08 02:00:23,RD,4.7,0,351442429

您将得到两个单词883427446627317909,1114259,1573178423,2019-11-08and 02:00:23,RD,4.7,0,351442429(即循环将针对这一行迭代两次)。这意味着您将进入该行的2019-11-08第一次迭代和0第二次迭代。

解决办法是不是引用命令替换,因为这样做会导致循环迭代一次读取到的文件的全部内容$line。解决办法是不是设置IFS为换行符,就像这样不优雅的cut(每次迭代都需要调用一次)。

相反,在一次调用中解析出您想要的数据cut并读取:

while IFS= read -r datetime; do
    # use "$datetime" here
done < <( cut -d, -f4 "$file" )

这使用进程替换来创建供while循环读取的输入流。该流中的数据将包含名为 的文件中的第四个逗号分隔字段$file

或者,while在子 shell 中使用循环:

cut -d, -f4 "$file" |
while IFS= read -r datetime; do
    # use "$datetime" here
done

使用awk,处理会更干净(除非您需要无论出于何种原因使用日期/时间值作为 shell 变量):

awk -F , '{ datetime = $4; ... more code here using the datetime variable }' "$file"

相关阅读:

答案2

cut如果我们愿意的话,我们实际上可以不用:

while IFS=, read _ _ _ stamp _ ; do
  echo "do something with $stamp here"
done < "$file"

稍微分解一下:

IFS=,暂时将记录分隔符设置为,

read _ _ _ stamp _将字段 1-3 和 5 向前存储在一次性变量中,同时将字段 4(您的日期/时间)捕获为stamp

< "$file"读入源文件(这是由我们的read命令捕获的)。

给这只猫换皮的另一种方法是,用每一行填充一个数组(这在 bash 中肯定有效,其他 shell 可能不支持它或以不同的方式实现它):

while IFS=, read -a line ; do echo "${line[3]}" ; done < "$file"

相关内容