查找文件中的条目数,并使用shell脚本删除这些实体

查找文件中的条目数,并使用shell脚本删除这些实体,shell,sed,grep,Shell,Sed,Grep,我有以下代码,我从系统中收集了所有大于40k的文件。我已将所有这些信息存储到一个文本文件中。我需要处理文件以读取文本文件中每个条目的出现次数,并删除所有这些条目。 我有以下代码,但它似乎不能正常工作 #! /bin/sh rm -rf /home/b/Desktop/CalcfileSizeGreater40.txt filename="/home/b/Desktop/fileSizeGreater40.txt" cat $filename | while read line

我有以下代码,我从系统中收集了所有大于40k的文件。我已将所有这些信息存储到一个文本文件中。我需要处理文件以读取文本文件中每个条目的出现次数,并删除所有这些条目。 我有以下代码,但它似乎不能正常工作

 #! /bin/sh
  rm -rf /home/b/Desktop/CalcfileSizeGreater40.txt
  filename="/home/b/Desktop/fileSizeGreater40.txt"   
  cat $filename | while read line
    do
  number_of_times=`cat $filename | grep $line | wc -l`
  echo $line:$number_of_times
  echo $line : $number_of_times >> /home/b/Desktop/CalcfileSizeGreater40.txt
  sed '/$line/d' $filename  >tmp
  mv tmp $filename
  done
当我查看CalcfileSizeGreater40.txt时,我可以看到

 131072 : 4
 65553 : 9
 65553 : 9
 65553 : 9
 65553 : 9
 65553 : 9
 65553 : 9
131072 : 4
 65553 : 9
 65553 : 9
 65553 : 9

关于我哪里出了问题,你有什么想法吗?

你可以简化这一行:

number_of_times=`cat $filename | grep $line | wc -l`
致:

当需要嵌套命令执行时,使用
$(…)
代替反引号是非常有益的。您可以使用
grep
计算出现次数,并且您不需要使用
cat
。养成在变量中用双引号括起文件名的习惯是一个好主意,以防文件名中有空格

编辑正在使用的
cat
文件不是一个好主意。由于您的操作方式,初始的
cat
将依次回显原始文件的每一行,完全忽略您使用编辑命令对同名(不同)文件所做的任何更改。这就是为什么你的一些名字在输出中出现了很多

但是,基本上您要做的是计算文件中每行出现的次数。这通常通过以下方式完成:

sort "$filename" |
uniq -c
sort
将文件中所有相同的行集合组合在一起,并且
uniq-c
统计每个不同行的出现次数。但是,它会在行前输出计数,因此必须将其反转-我们可以使用
sed
。因此,您的脚本可以是:

sizefile="/home/b/Desktop/CalcfileSizeGreater40.txt"
rm -f "$sizefile"
filename="/home/b/Desktop/fileSizeGreater40.txt"
sort "$filename" |
uniq -c |
sed 's/^[     ]*\([0-9][0-9]*\)[     ]\(.*\)/\2 : \1/' > "$sizefile"
在您的
CalcfileSizeGreater40.txt
上使用
rm-fr
时,我会非常谨慎
rm-f
对于一个文件来说已经足够了,如果它不是一个文件而是一个目录,您可能不想删除它

这样做的一个令人愉快的副作用是,代码比原始代码的效率要高得多,因为它可以让一个人通过文件(除非文件太大,排序必须将其拆分才能处理)


我发现
sed
代码有点难以理解

我应该解释一下,
[]
位表示空白和制表符。在我的机器上,
uniq
似乎只生成空格,因此您可以将其简化为:

sed 's/^ *\([0-9][0-9]*\) \(.*\)/\2 : \1/'

正则表达式先查找一行的开头、任意数量的空格,然后查找一个数字(由于包含它的
\(…\)
而将其记为
\1
),后跟一个空格,然后再查找“其他所有内容”,也会将其记为“\2”)。然后,替换项打印“其他所有内容”,后跟空格、冒号、空格和计数。

您可以简化此行:

number_of_times=`cat $filename | grep $line | wc -l`
sort -g $filename | uniq -c
致:

当需要嵌套命令执行时,使用
$(…)
代替反引号是非常有益的。您可以使用
grep
计算出现次数,并且您不需要使用
cat
。养成在变量中用双引号括起文件名的习惯是一个好主意,以防文件名中有空格

编辑正在使用的
cat
文件不是一个好主意。由于您的操作方式,初始的
cat
将依次回显原始文件的每一行,完全忽略您使用编辑命令对同名(不同)文件所做的任何更改。这就是为什么你的一些名字在输出中出现了很多

但是,基本上您要做的是计算文件中每行出现的次数。这通常通过以下方式完成:

sort "$filename" |
uniq -c
sort
将文件中所有相同的行集合组合在一起,并且
uniq-c
统计每个不同行的出现次数。但是,它会在行前输出计数,因此必须将其反转-我们可以使用
sed
。因此,您的脚本可以是:

sizefile="/home/b/Desktop/CalcfileSizeGreater40.txt"
rm -f "$sizefile"
filename="/home/b/Desktop/fileSizeGreater40.txt"
sort "$filename" |
uniq -c |
sed 's/^[     ]*\([0-9][0-9]*\)[     ]\(.*\)/\2 : \1/' > "$sizefile"
在您的
CalcfileSizeGreater40.txt
上使用
rm-fr
时,我会非常谨慎
rm-f
对于一个文件来说已经足够了,如果它不是一个文件而是一个目录,您可能不想删除它

这样做的一个令人愉快的副作用是,代码比原始代码的效率要高得多,因为它可以让一个人通过文件(除非文件太大,排序必须将其拆分才能处理)


我发现
sed
代码有点难以理解

我应该解释一下,
[]
位表示空白和制表符。在我的机器上,
uniq
似乎只生成空格,因此您可以将其简化为:

sed 's/^ *\([0-9][0-9]*\) \(.*\)/\2 : \1/'
正则表达式先查找一行的开头、任意数量的空格,然后查找一个数字(由于包含它的
\(…\)
而将其记为
\1
),后跟一个空格,然后再查找“其他所有内容”,也会将其记为“\2”)。然后,替换项打印“其他所有内容”,后跟空格、冒号、空格和计数

sort -g $filename | uniq -c
你将在每一行中得到(乘以数字)

10    500000
1     10000
sort -g $filename | uniq -c | while read a b; do echo $b $a ; done
你只需要交换每一行

10    500000
1     10000
sort -g $filename | uniq -c | while read a b; do echo $b $a ; done
你将在每一行中得到(乘以数字)

10    500000
1     10000
sort -g $filename | uniq -c | while read a b; do echo $b $a ; done
你只需要交换每一行

10    500000
1     10000
sort -g $filename | uniq -c | while read a b; do echo $b $a ; done

非常感谢您对上述内容的详细解释。我发现sed代码有点难以理解。现在是我绞尽脑汁去理解这一点的时候了。非常感谢您对以上的详细解释。我发现sed代码有点难以理解。是我绞尽脑汁去理解这一点的时候了。