Linux命令行使用for循环和格式化结果

时间:2017-11-06 12:46:50

标签: linux loops awk find md5

如何使用一个命令行提供特定大小之间的所有文件的列表,然后使用名称,md5和文件大小格式化文件。

示例输出应为

file1.***     MD5 value   size
file2.***     MD5 value   size etc.

我尝试了以下内容,但它在另一行显示md5

find 'directory' -size +30000c -size -50000c | 
while read filename 
   do ls -l "$filename" | awk '{print $9 "\t" $5}' 
   md5sum "$filename" | awk '{print $1}' 
done

它在单独的行上输出MD5的跟随

file1.***   size
MD5

file2.***   size
MD5

3 个答案:

答案 0 :(得分:1)

你非常接近,只需要一些修复:

#!/bin/bash
find ./path/to/dir -type f -size +30000c -size -50000c -printf '%s %p\n' |
while read -r size filename; do
    md5=$(md5sum "$filename" | awk '{print $1}')
    printf "%-30s %s %10s\n" "$filename" "$md5" "$size"
done

产生类似的东西:

./CHECKSUM                     36e371280a17372537a78167ce22b773        30400
./Makefile                     d21464a020be753a9d821cba58f046bc        40000

让我们从find开始。我们可以直接从find通过-printf action获取文件名(路径)和大小%p指定文件的完整文件名(相对路径)和%s。我们首先放置%s,因此read可以解析它,以防文件名包含空格。另外,我们只对文件感兴趣,因此我们会使用-type f过滤器。

接下来,read可以读取多个字段(由IFS分隔,默认为空格,换行符和制表符)。如果字段多于给定的变量,则最后一个变量将保留所有剩余字段。此外,我们使用-r来防止(特殊)解释输入中的转义字符。对于读取的每一行(假设您的文件名不包含换行符),我们使用您已使用的命令计算MD5总和。

最后,我们使用shell的内置printf来格式化并打印所有字段。格式化迷你语言类似于C&s的printf:%-30s表示例如左对齐的30个字符的宽字符串字段。

加分:使用换行处理文件名。可能不包含的一个字符Unix文件名是NULL(\0)字符。虽然bash在处理二进制(非文本)数据方面不是特别擅长,但我们仍然可以这样做:

#!/bin/bash
find ./path/to/dir -type f -size +30000c -size -50000c -printf '%s %p\0' |
while read -r -d '' size filename; do
    md5=$(md5sum "$filename" | awk '{print $1}')
    display_name=$(echo -n "$filename" | tr '\n' '?')
    printf "%-30s %s %10s\n" "$display_name" "$md5" "$size"
done

首先,我们使用\0中的-printf来将记录find输出与匹配的read -d ''分开。要使文件名适合在一行中打印,我们必须使用类似\n的内容替换(但仅用于显示)所有换行?。我们可以使用trecho -n结合使用(注意我们不能使用here-string <<<"$filename"代替echo,因为here-string adds a trailing newline )。

答案 1 :(得分:1)

您可以使用rhash执行此简单任务

find dir/ -type f -size +30000c -size -50000c -exec rhash -p "%p %m %s\n" {} \;
  • -p以自定义格式打印
  • %p用于文件路径,%m用于md5sum,%s用于文件大小(以字节为单位)

答案 2 :(得分:0)

不要直接找到一组命令,只需直接在find:

中调用这些命令
@Bean
public ServletRegistrationBean pingServletDispatcher() {
    DispatcherServlet dispatcherServlet = new DispatcherServlet();

    //XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
    //applicationContext.setConfigLocation("classpath:/META-INF/spring/webmvc-context.xml");
    //dispatcherServlet.setApplicationContext(applicationContext);

    ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/ping/*" /* or /* / */);
    servletRegistrationBean.setName("ping");

    return servletRegistrationBean;
}

请注意,find /p/a/t/h -size +30000c -size -50000c -exec sh -c ' printf "%s\t" "$1"; md5sum "$1" | cut -d " " -f 1 | tr -d \\n; printf "\t"; stat -c %s "$1"' _ {} \; 是非标准的,但上述内容适用于debian。您可能需要stat。 YMMV