帮助使用 Bash 脚本或某些程序对文件进行排序并移动到不同的文件夹

帮助使用 Bash 脚本或某些程序对文件进行排序并移动到不同的文件夹

有谁能帮我用 bash 脚本或终端命令(甚至是一个小 Java 程序)对一些文件进行排序,这些文件可以用来对文件进行排序并将文件移动到新文件夹?我已经尝试了好几天,但还没有找到办法。

我有一个名为“网页”的文件夹,里面有数百个 html 文件。粗略地说,它们分为三类,因此我需要使用不同的变量运行一个脚本三次,或者运行一个可以一次性完成所有排序和移动的脚本。

我想在文件中搜索某些字符串,然后将匹配的文件发送到新文件夹。为了简单起见,有些网页是关于政治的,有些是关于商业的,有些是关于计算机的。因此,假设我想在文件夹“网页”中的所有文件中搜索单词“选举”、“股市”和“开源”,并将包含单词“选举”的文件移动到名为“政治”的文件夹,将包含单词“股市”的文件移动到名为“商业”的文件夹,将包含术语“开源”的文件移动到名为“计算机”的文件夹。

就像我说的,我曾尝试过弄清楚,但我的努力却被人嘲笑。我不是专家。谢谢!

答案1

假设当前目录中有以下文件:

  • a/sm1,内容为“a 股票市场 b”
  • b/sm2,内容为“x 股票市场 y”
  • sm3,确实如此不是包含“股市”
  • destination,要移动包含以下内容的文件的目录“股市”

f让我们查找当前目录中的所有文件(类型= 文件)( .):

$ find . -type f
./a/sm1
./sm3
./b/sm2

sm3不包含“股票市场”,我们不想要它。在我们现在拥有的文件列表中,让我们搜索“股票市场”,并仅显示匹配的文件:

$ find . -type f | xargs grep --files-with-matches "stock market"
./a/sm1
./b/sm2

现在让我们获取每个文件,并将它们移动到destination目录中:

$ for f in $(find . -type f | xargs grep --files-with-matches "stock market"); do mv $f destination/; done

确保在运行此操作之前已备份,以防它不能按照您想要的方式移动它们。

答案2

我认为一些简单的 bash 魔法可能会起到作用:

#!/bin/bash
dir1=""
dir2=""
dir3=""
shopt -s nullglob
for i in *.html)
    do if [ "$(grep 'keyword1' $i)" != "" ]; then
        mv -vf "$i" "$dir1"
    elif [ "$(grep 'keyword2' $i)" != "" ]; then
        mv -vf "$i" "$dir2"
    elif [ "$(grep 'keyword3' $i)" != "" ]; then
        mv -vf "$i" "$dir3"
    else
        echo "$i">>nomatch
    fi
done
cat nomatch

答案3

这里有几种方法可以实现你的愿望:

1.find

find . -iname '*html' -type f -exec grep -q election "{}" \; -and -exec mv {} politics/ \; 

解释

这里我们使用 find 的-exec选项:

-exec command ;
      Execute  command;  true  if 0 status is returned.  All following
      arguments to find are taken to be arguments to the command until
      an  argument  consisting of `;' is encountered.  The string `{}'
      is replaced by the current file name being processed

因此,第一个-exec搜索文件(此处用 表示{}election,第二个将执行移动。 确保仅当第一个成功且文件与模式匹配时,才会运行-and第二个。-exec

2. find&外壳。

这与 Cos64 的答案中的方法基本相同,但有一些改进。

find . -iname '*html' -type f -print0 | 
    while IFS= read -r -d '' file; do 
        grep -q election "$file" && mv "$file" politics/
    done

解释

  • find命令将查找所有名称以(或,不区分大小写)-type f结尾的文件( ),并以 NULL 字符分隔它们。这是必要的,因为 *nix 系统中的文件名可以包含除和(NULL) 之外的任何字符。因此,您可以拥有包含空格、换行符和任何其他奇怪字符的文件。这些需要特殊处理。.html.HTML-iname/\0
  • while IFS= read -r -d '' file; do ... done:这将迭代 的输出find,将每个文件另存为$file。 将IFS=输入字段分隔符设置为无,这意味着我们可以正确处理文件名中的空格。 使其-d ''读取\0- 分隔的行,并-r使其处理包含 的文件名\
    • grep -q election "$file":在文件中搜索模式。-q抑制正常输出并使其grep静默。
    • && echo mv "$file" politics/&&确保仅当前一个命令(grep)成功时才会运行此命令。

3. 猛击。

该脚本与@WilhelmErasmus 的非常好的答案中的脚本非常相似,不同之处在于i)它可以从命令行获取一组模式和替换;ii)它还可以在子目录中查找文件。

#!/usr/bin/env bash

## Exit if no arguments were given
[ -z "$1" ] && echo "At least two arguments are needed." >&2 && exit 1
## Collect the arguments
args=("$@")
## Declare the $dirs associative array
declare -A dirs

## Save the arguments given in the $dirs array.
## $# is the number of arguments given, so this
## will iterate over of them, reading two by two.
for ((i=0;i<$#;i+=2)); 
do
    ## The arguments are pairs of patterns and target directories.
    ## Set the value of this pattern to the value of the next argument,
    ## its target directory. 
    dirs[${args[$i]}]="${args[i+1]}"
done

## Ignore globs that match no files
shopt -s nullglob
## This enables ** to match subdirectories
shopt -s globstar
## Find all .html files
for file in **/*{html,htm,HTM,HTML}
do
    matched=0;
    for pat in "${!dirs[@]}"
    do
        ## Does this file match the pattern?
        ## The `-q` suppresses grep's output.
        grep -q "$pat" "$file" && 
        ## Set matched to 1 if the file matches.
        matched=1 &&
        ## If the grep succeeded, move the file
        ## to the corresponding directory
        mv "$file" "${dirs[$pat]}" && 
        ## If the move succeeded, break the loop
        ## and move to the next pattern.
        break 
    done
    ## Report files that didn't match
    [[ "$matched" -eq 0 ]] && printf "No matches for '%s'\n" "$file" >&2
done

运行脚本并为其指定模式及其目标的名称。例如,使用您问题中的那些:

bash move_files.sh "election" "politics" "stock market" "business" "open source" "computers" 

相关内容