【问题标题】:finding and moving files via grep, or awk?通过 grep 或 awk 查找和移动文件?
【发布时间】:2015-05-06 09:09:22
【问题描述】:

有没有办法使用 grep、awk 和管道来执行以下操作:

考虑一个父文件夹 A,其中有四个文件夹 B、C、D、E。每个文件夹中的层数未知。我想在每个文件夹 B、C、D、E 的层次结构中查找 .pdf 文件。这可以通过 find 完成:

find . -type f -name "*.pdf"

找到文件后,我会将其移至另一个文件夹。因此,在 B 下找到的 .pdf 文件将被移动到父文件夹中新创建的名为 B_NEW 的文件夹中,依此类推。我不知道如何使用管道并创建文件夹并进行移动/复制!

【问题讨论】:

  • 批量使用 find 对文件夹中的每个文件(在临时文件中),grep -c 对列表搜索 .pdf,如果有的话,sed 生成每个文件的复制命令(添加 cp)并作为具有相同名称的目的地,但通过一个非常简单的s/// 复制路径的 2 第一级。
  • @NeronLeVelu 有道理,但不知道怎么做!
  • @user3639557 你要复制到哪里?您需要在脚本中创建新的目录结构还是已经存在?
  • @JID 刚刚更新了问题。
  • @user3639557 BB 在哪里?在同一个文件夹中,你如何决定新文件夹的名称?

标签: bash awk grep


【解决方案1】:
TempList=/tmp/ListOfParentFile.tmp
ParentFolder=A
here="$( pwd )"

cd ${ParentFolder}/..
find ${ParentFolder##*/} -print > ${TempList}
if [ $( grep -c -E -e '.pdf$' ${TempList} ) -gt 0 ]
 then
   mkdir "${ParentFolder##*/}${ParentFolder##*/}"

   echo 'set -vx' > ${TempList}.action
   sed -n '\#^\([^/]*\)/\([^/]*\)$#  s##cp -fr &* \1\1/\2\2#p' ${TempList} >> ${TempList}.action
   . ${TempList}.action

   rm ${TempList}*
   cd ${here}
 fi

这个概念又快又脏,为此添加任何安全性。在 KSH/AIX 中测试

说明

  • 初始化一些稍后使用的变量
    • 要检查的父文件夹(很容易用这个循环)
    • 临时文件名
    • 调用文件夹(我们稍后使用 cd 以便更轻松地使用父文件夹(之后调用 参考文件夹)文件夹的结果)
  • 转到参考文件夹的父级(上)
  • 通过 find 将 Reference 文件夹(包括子文件夹)中的所有文件放入临时文件中
  • grep文件看里面是否有pdf(de if里面的子进程)
  • 如果有 pdf
    • 使用引用文件夹${ParentFolder##*/}double 名称创建一个文件夹(与Reference 相同级别)两次。使用 shell 功能删除最后一个 / 之前的字符串的任何部分
    • 创建一个临时 action 文件并设置 -vx 以跟踪活动(set -vx 是可选的,而不是文件)
    • 在临时文件上使用 sed(首先使用 find 生成文件)根据每个行条目生成一组操作,这些条目的结构为 Reference/Subfolder,递归地复制文件夹和内容。其他行被丢弃,因此仅处理参考文件夹中的第一级子文件夹。
    • 在当前 shell 中运行临时操作文件(本例中为批处理)
    • 清理临时文件
    • 回到起始文件夹

【讨论】:

  • 你能补充解释吗?我不知道其中一半是做什么的,但看起来很有趣!
  • :-) 此评论与保存我的回复版本之间存在一些延迟
【解决方案2】:

这应该可行

while read file;do
        dir="New_${file#*/}" #strip to first / and add "New_"
        dir="${dir%/*}" #strip off filename
        if [[ ! -d "$dir" ]];then #check directory exists or not
                echo "creating directory structure $dir"
                mkdir -p "$dir" || (echo "failed to create $dir.Aborting for this file" && continue) # make the directory and continue to next file if this fails
        fi
        echo "copying $file -> $dir/"
        cp "$file" "$dir/" || (echo "failed to copy $file.Aborting for this file" && continue) #Copy the file to newly created dir

done< <(find . -type f -name "*.pdf") #find the files

测试

$find . -type f -name "*.pdf"
./A/4.pdf
./A/3.pdf
./A/1.pdf
./A/2.pdf
./C/4.pdf
./C/3.pdf
./C/1.pdf
./C/2.pdf
./B/7.pdf
./B/8.pdf
./B/6.pdf
./B/5.pdf
./D/7.pdf
./D/8.pdf
./D/6.pdf
./D/5.pdf

.

$./Scipt
creating directory structure New_A
copying ./A/4.pdf -> New_A/
copying ./A/3.pdf -> New_A/
copying ./A/1.pdf -> New_A/
copying ./A/2.pdf -> New_A/
creating directory structure New_C
copying ./C/4.pdf -> New_C/
copying ./C/3.pdf -> New_C/
copying ./C/1.pdf -> New_C/
copying ./C/2.pdf -> New_C/
creating directory structure New_B
copying ./B/7.pdf -> New_B/
copying ./B/8.pdf -> New_B/
copying ./B/6.pdf -> New_B/
copying ./B/5.pdf -> New_B/
creating directory structure New_D
copying ./D/7.pdf -> New_D/
copying ./D/8.pdf -> New_D/
copying ./D/6.pdf -> New_D/
copying ./D/5.pdf -> New_D/

.

find . -type f -name "*.pdf"
./A/4.pdf
./A/3.pdf
./A/1.pdf
./A/2.pdf
./C/4.pdf
./C/3.pdf
./C/1.pdf
./C/2.pdf
./New_C/4.pdf
./New_C/3.pdf
./New_C/1.pdf
./New_C/2.pdf
./New_A/4.pdf
./New_A/3.pdf
./New_A/1.pdf
./New_A/2.pdf
./B/7.pdf
./B/8.pdf
./B/6.pdf
./B/5.pdf
./New_B/7.pdf
./New_B/8.pdf
./New_B/6.pdf
./New_B/5.pdf
./New_D/7.pdf
./New_D/8.pdf
./New_D/6.pdf
./New_D/5.pdf
./D/7.pdf
./D/8.pdf
./D/6.pdf
./D/5.pdf

【讨论】:

  • 它不起作用。我收到以下错误:1) cp: cannot stat some-file-name 2) No such file or directory 3) cp: omitting directory
  • 你完全复制了它并且你正在使用 bash ?您的文件夹/文件的名称或换行符中是否有空格或奇怪的东西
  • 是的。我用下划线替换空格、. 等。对于一半的文件夹,它会创建新的,对于剩下的一半,它会出错。
  • 对不起,我不明白。您能否在问题之前和之后放置文件夹名称的示例?以给出错误的例子为例。
  • 例如:cp: 省略目录‘1’
猜你喜欢
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 2021-12-26
  • 2020-06-24
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
相关资源
最近更新 更多