2016-07-11 46 views
1

我要复制的文件具有100线以上到另一个文件夹的文件:如何复制其到其他文件夹行数> 100

$ cd "/home/john/folder a" 
$ wc -l * 
10 file1.txt 
50 file2.txt 
100 file3.txt 
150 file4.txt 

我要复制文件file3.txtfile4.txt(文件有100行或更多)到文件夹/home/john/folder b

有人可以帮我吗?非常感谢你。

回答

2

试试这个:

declare -i numfile 
for f in *; do 
    numfile=$([ -f "$f" ] && cat "$f" | wc -l) 
    [ $numfile -ge 100 ] && cp "$f" otherdir 
done 

对于每个文件在当前目录中,numfile指定文件的行数。

如果numfile大于或等于100,则将文件复制到otherdir

编辑:

正如威廉Pursell mentionned,一个更强大的方法是测试,如果项目是文件之前执行的比较和复制命令:

for f in *; do 
    if [ -f "$f" ]; then 
    [ "$(wc -l < $f)" -ge 100 ] && cp "$f" otherdir; 
    fi 
done 
+0

我想你的答案是肯定更重要的是比我:) – Will

+0

上numfile的声明作为依托整数味道不好。例如,如果将测试反转为复制少于100行的文件,则会尝试复制目录。在做numfile分配的行的末尾附加'&&'可能更安全,或者写'for f in *; test -f“$ f”&& test“$(wc -l <​​$ f)”-ge 100 && cp“$ f”/ path;完成' –

+0

[-f“$ f”]是什么意思? – Jiangty

0

试着这么做这个(POSIX sh):

#!/bin/sh 
SOURCE_FOLDER="/home/john/folder a" 
COPY_TO="/home/john/folder b" 

for dir in "$SOURCE_FOLDER" "$COPY_TO"; do 
    if [ ! -d "$dir" ]; then 
     echo "Directory ${dir} does not exist." >&2 
     exit 1 
    fi 
done 

if [ "x`ls -A "$SOURCE_FOLDER"`" = "x" ]; then 
    echo "Directory '${SOURCE_FOLDER}' is empty." >&2 
    exit 1 
fi 

for file in "$SOURCE_FOLDER"/*; do 
    LINES=`wc -l < "$file"` 
    echo "File ${file} has ${LINES} lines..." 

    if [ "$LINES" -ge 100 ]; then 
     echo "Copying ${file}..." 
     cp -a "$file" "${COPY_TO}/" 
    fi 
done 

这是一个Bash版本与巴什系统(你说的Unix,而不是Linux,那么你可能想顶配版本):

#!/bin/bash 
SOURCE_FOLDER="/home/john/folder a" 
COPY_TO="/home/john/folder b" 

for dir in "$SOURCE_FOLDER" "$COPY_TO"; do 
    if [[ ! -d "$dir" ]]; then 
     echo "Directory ${dir} does not exist." >&2 
     exit 1 
    fi 
done 

if [[ -z "$(ls -A "$SOURCE_FOLDER")" ]]; then 
    echo "Directory '${SOURCE_FOLDER}' is empty." >&2 
    exit 1 
fi 

for file in "$SOURCE_FOLDER"/*; do 
    LINES="$(wc -l < "$file"')" 
    echo "File ${file} has ${LINES} lines..." 

    if [[ "$LINES" -ge 100 ]]; then 
     echo "Copying ${file}..." 
     cp -a "$file" "${COPY_TO}/" 
    fi 
done 

我测试它像这样:

$ mkdir "folder a" 
$ mkdir "folder b" 
$ chmod +x script.sh 
$ cd folder\ a/ 
$ seq 1 1000 > file1.txt 
$ seq 1 1000 > file2.txt 
$ seq 1 100 > file4.txt 
$ seq 1 100 > file3.txt 
$ seq 1 99 > file4.txt 
$ seq 1 1 > file5.txt 
$ seq 1 20 > file6.txt 
$ cd .. 
$ ./script.sh 
File /.../dev/scratch/stack/folder a/file1.txt has 1000 lines... 
Copying /.../dev/scratch/stack/folder a/file1.txt... 
File /.../dev/scratch/stack/folder a/file2.txt has 1000 lines... 
Copying /.../dev/scratch/stack/folder a/file2.txt... 
File /.../dev/scratch/stack/folder a/file3.txt has 100 lines... 
Copying /.../dev/scratch/stack/folder a/file3.txt... 
File /.../dev/scratch/stack/folder a/file4.txt has 99 lines... 
File /.../dev/scratch/stack/folder a/file5.txt has 1 lines... 
File /.../dev/scratch/stack/folder a/file6.txt has 20 lines... 

我鼓励你逐步完成此行,线,确定脚本的每个部分如何工作,以帮助您在未来完成类似的任务。

我会在这里解释一下几件事情:

  • wc -l < "$file"给了我们只有文件的行数,不带文件。
  • [ "$LINES" -ge 100 ]如果文件中至少有100行,则为true。
  • echo "..." >&2输出一行到标准错误而不是标准输出。
  • cp -a复制一个文件,同时保留它的所有属性,如所有者,权限和修改时间。
  • 确保引用所有变量,除非您有充分的理由不去防止空白问题。
+0

你并不需要一个管道来获得行数。 'wc -l <​​“$ file”'也可以。 – user1934428

+0

优秀的点,纠正!谢谢。 – Will

1

这里是一个更:

# Assuming that we are in source folder ... 
cp $(wc -l *|grep -Eo '[0-9]{3,} (.*)'|head -n -1|cut -d ' ' -f 2) /dev/null "/home/john/folder b" 

head删除由wc打印线,/dev/null需要,你没有匹配的绕圈任何文件的情况下照顾。

当然这种解决方案 - 为这里提出其他的人 - 让您进入的问题,如果你的源目录中包含许多文件,这些文件的最大命令行长度将被超过。

+0

我喜欢这个想法,但使用正则表达式匹配数值比较似乎很脆弱。可能更容易做'wc -l * | awk'$ 1> 100 {print $ 2}'...'目录仍然存在问题。 –

+0

在我的解决方案中,目录被隐式忽略。我没有看到与数字正则表达式匹配是问题,除了与一个(slightliy病理情况下),那里有我的做法会失败:想象一下,一个名为'200 xx'(即名称以三个数字开始,有嵌入的空间);用我的解决方案,即使文件少于100行,文件也会被复制。当然,谁会用名称中的嵌入空格创建文件.... ;-) – user1934428

相关问题