给定一个带有文件名列表(带文件路径)的文件,例如:
input.txt (contents):
/2018/06/01/abc.txt
/2018/06/01/xyz.txt
/2018/06/02/abc.txt
/2018/06/02/xyz.txt
/2018/06/03/xyz.txt
/2018/06/03/abc.txt
/2018/06/01/ghi.txt
...必须每个日期创建一个文件,只有与该日期对应的文件名(所有使用标准Unix命令)例如,预期输出:
cat 2018-06-01.txt =>
/2018/06/01/abc.txt
/2018/06/01/xyz.txt
/2018/06/01/ghi.txt
cat 2018-06-02.txt =>
/2018/06/02/abc.txt
/2018/06/02/xyz.txt
同样适用于所有其他日期。
使用awk:
$ awk '
{
split($0,a,/[/.]/) # split record on chars ./
f=a[2] "-" a[3] "-" a[4] ".txt" # make filename
print >> f # print (appending) to file
close(f) # close the file to preserve fds
}' input.txt
创建的文件:
$ ls
2018-06-01.txt
2018-06-02.txt
2018-06-03.txt
文件内容:
$ cat 2018-06-01.txt
/2018/06/01/abc.txt
/2018/06/01/xyz.txt
/2018/06/01/ghi.txt
请注意,没有错误检查。
使用GNU awk for gensub()和内部打开文件控件:
awk '{print > gensub("/([^/]+)/([^/]+)/([^/]+)/[^.]+","\\1-\\2-\\3",1)}' file
你能不能尝试一下,詹姆斯先生有点不同的方法,我只关闭输出文件,当它的值在Input_file(第2,第3和第4个字段)中改变而不等于之前的输出文件名(而不是关闭它)在每一行)。还使用/
作为线的场分离器。
awk '
BEGIN{
FS="/"
OFS="-"
}
{
file=$2 OFS $3 OFS $4".txt"
}
prev!=file{
close(prev)
prev=file
}
{
print >> (file)
}' Input_file
使用简单的bash脚本。
#!/bin/bash
set -e
for i in `cat input.txt`
do
y=`echo $i|cut -d "/" -f2`
m=`echo $i|cut -d "/" -f3`
d=`echo $i|cut -d "/" -f4`
f_name=`echo "${y}-${m}-${d}.txt"`
echo $i >>$f_name
done
Ed Morton编辑(见下面的评论)
只是修复上面的反模式和错误,但实际上并没有改善它,但仍然没有暗示这是一个合理的方法:
#!/bin/env bash
set -e
while read -r i; do
y=$(echo "$i"|cut -d '/' -f2)
m=$(echo "$i"|cut -d '/' -f3)
d=$(echo "$i"|cut -d '/' -f4)
f_name="${y}-${m}-${d}.txt"
echo "$i" >>"$f_name"
done < input.txt