我想将 100 行或更多行的文件复制到另一个文件夹:
$ cd "/home/john/folder a"
$ wc -l *
10 file1.txt
50 file2.txt
100 file3.txt
150 file4.txt
我想将文件file3.txt
和file4.txt
(具有 100 行或更多行的文件)复制到文件夹/home/john/folder b
。
有人可以帮我吗?谢谢。
试试这个:
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
。
编辑:
正如 William Pursell 所提到的,更可靠的方法是在执行比较和复制命令之前测试项目是否为文件:
for f in *; do
if [ -f "$f" ]; then
[ "$(wc -l < $f)" -ge 100 ] && cp "$f" otherdir;
fi
done
这里还有一个:
# 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
处理您没有任何与标准匹配的文件的情况。
当然,这个解决方案 - 正如这里介绍的其他解决方案 - 会给你带来问题,如果你的源目录包含那么多文件,就会超过最大命令行长度。
尝试这样的事情(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,所以你可能想要顶级版本)的Bash版本:
#!/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"
只给我们文件的行数,没有文件名。 - 如果文件中至少有 100 行,则
[ "$LINES" -ge 100 ]
为 true。 -
echo "..." >&2
输出线路到标准误差而不是标准输出。 -
cp -a
复制文件,同时保留文件的所有属性,例如所有者、权限和修改时间。 - 确保引用所有变量,除非您有充分的理由不这样做,以防止出现空格问题。