我有一个目录结构有超过50,000个文件。 文件名的forms是<YYMMDD>-<NNN>.htm
。
目录结构是
/<category>/<YYYY>/<MM>/
例如:
./Racing/1998/03/980320-001.htm ./Racing/1998/03/980320-002.htm ... ./General/1999/02/990221-001.htm ./General/1999/02/990221-002.htm ...
我想要的文件的平面列表的forms
<category>-<YYYY>-<MM>-<DD>-<NNN>
所以上面是
Racing-1998-03-20-001.htm Racing-1998-03-20-002.htm ... General-1999-02-21-001.htm General-1999-02-21-002.htm
我(重新)学习bash和正则expression式,并会欣赏一些关于如何实现这一点的指针。
我知道如何生成path列表,但不知道如何应用正则expression式来转换表单。 我会使用find -type f -name "*.htm" | <some goblygook here>
find -type f -name "*.htm" | <some goblygook here>
这里<some goblygook here>
可能会利用xargs
…
提前致谢。
[编辑3/30 9:58 pm]
根据下面的答案,我编造了这个脚本。 我不能让xargs
工作:
#!/bin/bash mkdir ./flat find -type f -name "*.htm" | \ awk -F'[/]' ' BEGIN{OFS="-"} { gsub(/^\.\//,"") ;print "./" $0 " ./flat/" $1,$2, substr($4,3,2),substr($4,5,2),substr($4,8)} ' | \ xargs -p -d "\n" -n 1 cp
运行这个给我:
$ ./awktest.sh mkdir: cannot create directory `./flat': File exists cp ./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm ?...y cp: missing destination file operand after `./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm' Try `cp --help' for more information. ^C
从该输出复制确切的cp
命令( cp ./General/1997/05/970525-002.htm ./flat/General-1997-05-25-002.htm
),并直接粘贴到bash提示符中。
我试图找出如何在-print0
命令上使用-print0
,但无法弄清楚如何让awk
使用\0
作为logging终止符( RS="\0"
不起作用)。 我认为这个问题与换行有关,但是我不知所措。
当awk
存在时通常不需要使用sed
。 这是另一个答案,不fork额外的sed
进程
find -type f -name "*.htm" | awk -F'[/]' 'BEGIN{OFS="-"}{ gsub(/^\.\//,"") ;print $1,$2, substr($4,3,2),substr($4,5,2),substr($4,8) }'
编辑,你可以在awk
做你的cp
find -type f -name "*.htm" | awk -F'[/]' 'BEGIN{OFS="-"}{ gsub(/^\.\//,"") source = $1 OFS $2 OFS substr($4,3,2) OFS substr($4,5,2) OFS substr($4,8) destination = <create your destination here> command = "cp "source" "destination system(command) }'
find -type f -name "*.htm" | sed 's@^./@@g;s@/@-@g' | awk -F'-' '{print $1 "-" $2 "-" $3 "-" substr($4, 5, 2) "-" $5}'
sed & awk对文本操作非常有用。
我不得不调整接受的答案为我工作:
find -type f -name "*.png" | awk -F'[/]' 'BEGIN{OFS="_"}{ gsub(/^\.\//,"") source = "source root folder" $1 "/" $2 "/" $3 destination = "destination folder" $1 OFS $2 OFS $3 command = "cp "source" "destination system(command) }'
要像这样复制文件:
eval "`find -type f -name "*.htm" |awk -F/ '{print "cp " $0 " " $2 "-" $3 "-" $4 "-" substr($5,5) ";" }'`"